文档章节

架构编译器框架系统 LLVM 使用简介

Konghy
 Konghy
发布于 2015/08/20 15:46
字数 2256
阅读 1320
收藏 11

LLVM 是什么
LLVM 是 low level virtual machine(底层虚拟机)的简称,它是一个开源的编译器架构,已经被成功应用到多个应用领域。LLVM 的主要作用是它可以作为多种语言的后端,它可以提供可编程语言无关的优化和针对很多种CPU的代码生成功能。LLVM 核心库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。LLVM的项目是一个模块化和可重复使用的编译器和工具技术的集合。LLVM是伊利诺伊大学的一个研究项目,提供一个现代化的,基于SSA的编译策略能够同时支持静态和动态的任意编程语言的编译目标。自那时以来,已经成长为LLVM的主干项目,由不同的子项目组成,其中许多正在生产中使用的各种 商业和开源的项目,以及被广泛用于学术研究。

LLVM 常用命令工具
llvm-as 将可读的 .ll 文件汇编成字节代码
llvm-dis 将字节代码文件反编成可读的 .ll 文件
opt 在一个字节代码文件上运行一系列的 LLVM 到 LLVM 的优化
llc 为一个字节代码文件生成本机器代码
lli 直接运行使用 JIT 编译器或者解释器编译成字节代码的程序
llvm-link 将几个字节代码文件连接成一个
llvm-ar 打包字节代码文件
llvm-ranlib 为 llvm-ar 打包的文件创建索引
llvm-nm 在 字节代码文件中打印名字和符号类型
llvm-prof 将 'llvmprof.out' raw 数据格式化成人类可读的报告
llvm-ld 带有可装载的运行时优化支持的通用目标连接器
llvm-config 打印出配置时 LLVM 编译选项、库、等等
llvmc 一个通用的可定制的编译器驱动
llvm-diff 比较两个模块的结构
bugpoint 自动案例测试减速器
llvm-extract 从 LLVM 字节代码文件中解压出一个函数
llvm-bcanalyzer 字节代码分析器 (分析二进制编码本身,而不是它代表的程序)
FileCheck 灵活的文件验证器,广泛的被测试工具利用
tblgen 目标描述阅读器和生成器
lit    LLVM 集成测试器,用于运行测试

LLVM IR
根据编译原理可知,编译器不是直接将源语言翻译为目标语言,而是翻译为一种“中间语言”,即“IR”。之后再由中间语言,利用后端程序和设备翻译为目标平台的汇编语言。由于中间语言相当于一款编译器前端和后端的“桥梁”,不同编译器的中间语言IR是不一样的,而IR可以说是集中体现了这款编译器的特征。

LLVM IR主要有三种格式:一种是在内存中的编译中间语言;一种是硬盘上存储的二进制中间语言(以.bc结尾),最后一种是可读的中间格式(以.ll结尾)。这三种中间格式是完全相等的。

LLVM IR是LLVM优化和进行代码生成的关键。根据可读的IR,我们可以知道再最终生成目标代码之前,我们已经生成了什么样的代码。而且根据IR,我们可以选择使用不同的后端而生成不同的可执行代码。同时,因为使用了统一的IR,所以我们可以重用LLVM的优化功能,即使我们使用的是自己设计的编程语言。

结构化编译器前端 Clang 介绍
Clang ( 发音为 /klæŋ/) 是 LLVM 的一个编译器前端,它目前支持 C, C++, Objective-C 以及 Objective-C++ 等编程语言。Clang 对源程序进行词法分析和语义分析,并将分析结果转换为 Abstract Syntax Tree ( 抽象语法树 ) ,最后使用 LLVM 作为后端代码的生成器。

Clang 的开发目标是提供一个可以替代 GCC 的前端编译器。与 GCC 相比,Clang 是一个重新设计的编译器前端,具有一系列优点,例如模块化,代码简单易懂,占用内存小以及容易扩展和重用等。由于 Clang 在设计上的优异性,使得 Clang 非常适合用于设计源代码级别的分析和转化工具。Clang 也已经被应用到一些重要的开发领域,如 Static Analysis 是一个基于 Clang 的静态代码分析工具。

由于 GNU 编译器套装 (GCC) 系统庞大,而且 Apple 大量使用的 Objective-C 在 GCC 中优先级较低,同时 GCC 作为一个纯粹的编译系统,与 IDE 配合并不优秀,Apple 决定从零开始写 C family 的前端,也就是基于 LLVM 的 Clang 了。Clang 由 Apple 公司开发,源代码授权使用 BSD 的开源授权。

Clang 的特性:
相比于 GCC,Clang 具有如下优点:
1. 编译速度快:在某些平台上,Clang 的编译速度显著的快过 GCC。
2. 占用内存小:Clang 生成的 AST 所占用的内存是 GCC 的五分之一左右。
3. 模块化设计:Clang 采用基于库的模块化设计,易于 IDE 集成及其他用途的重用。
4. 诊断信息可读性强:在编译过程中,Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告。
5. 设计清晰简单,容易理解,易于扩展增强。与代码基础古老的 GCC 相比,学习曲线平缓。

当前 Clang 还处在不断完善过程中,相比于 GCC, Clang 在以下方面还需要加强:
1. 支持更多语言:GCC 除了支持 C/C++/Objective-C, 还支持 Fortran/Pascal/Java/Ada/Go 和其他语言。Clang 目前支持的语言有 C/C++/Objective-C/Objective-C++。
2. 加强对 C++ 的支持:Clang 对 C++ 的支持依然落后于 GCC,Clang 还需要加强对 C++ 提供全方位支持。
3. 支持更多平台:GCC 流行的时间比较长,已经被广泛使用,对各种平台的支持也很完备。Clang 目前支持的平台有 Linux/Windows/Mac OS。

本段内容参考:http://www.ibm.com/developerworks/cn/opensource/os-cn-clang/

Clang 编译选项
clang    [-c|-S|-E] -std=standard -g
         [-O0|-O1|-O2|-O3|-Ofast|-Os|-Oz|-O|-O4]
         -Wwarnings... -pedantic
         -Idir... -Ldir...
         -Dmacro[=defn]
         -ffeature-option...
         -mmachine-option...
         -o output-file
         -stdlib=library
         input-filenames

大部分选项与 gcc 类似:

-c 只是编译不链接,生成目标文件“.o”

-S 只是编译不汇编,生成汇编代码

-E 只进行预编译,不做其他处理

-g 在可执行程序中包含标准调试信息

-o file 把输出文件输出到file里
-I dir 在头文件的搜索路径列表中添加dir目录

-L dir 在库文件的搜索路径列表中添加dir目录

中间码的创建与转化
编译生成二进制的 .bc 文件(bitcode file): clang -emit-llvm -c xx.c -o xx.bc

编译生成 LLVM 的汇编代码 .ll 文件( LLVM assembly code): clang -emit-llvm -S xx.c -o xx.ll

.bc 和 .ll 文件都可以直接用 lli 来执行。

将 .ll 文件转化为 .bc 文件: llvm-as test.ll

将 .bc 文件转化为 .ll 文件: llvm-dis test.bc

将 .bc 或 .ll 文件转化为本机平台的汇编代码: llc test.bc llc test.ll llc test.bc -o test.s

即时编译器 JIT 简介
LLVM 中间码的执行需要用到 Jit。那么,JIT到底是个什么东西呢。其实,JIT 是一个即时编译器,即 Just-in-time Compiler。对于 JIT 的了解我也知之胜少,它的作用大概就是对中间码进行编译作业,像 JAVA 这种跨平台的语言也是通过 JIT 实现的。在执行 LLVM 的 lli 工具时,会去调用 JIT 将中间码编译成本机架构的机器码再执行。

至于 jit 与 mcjit 的区别,大概是 jit 是 LLVM 旧版本的支持,而 mcjit 是对 jit 新的支持。mc是机器码的意思,即 Machine Code。在 Wikipedia 看到说,以前的 LLVM 会依赖与本机系统的汇编器或者提供一套工具链,然后再翻译成机器码。而通过整合过的 LLVM MC 能够支持大多数的机器架构,包括 x86, x86-64, ARM, ARM64 以及 大部分的 MIPS 架构等。

© 著作权归作者所有

共有 人打赏支持
Konghy
粉丝 7
博文 22
码字总数 31889
作品 0
朝阳
程序员
私信 提问
Swift 编程语言首席架构师 Chris Lattner 简介

Chris Lattner(1978年出生)是 LLVM 项目的主要发起人与作者之一,Clang 编译器的作者。他现在是苹果公司『开发者工具』部门的主管,领导 Xcode、Instruments 和 编译器团队,从 2010 年 7 ...

oschina
2014/06/05
10.5K
36
iOS底层探索(一) - 从零开始认识Clang与LLVM

写在前面: 本系列为 『iOS底层探索系列』第一篇,本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举...

Developer_CYX
2017/12/20
0
0
LLVM学习笔记——目录

前言 2011年前后,GCC后端代码的阅读陷入了举步维艰的境地。GGC-3.4.6后端代码的可读性不友好(当前版本没看过,不予评价。不过据说4.0进行的重构,应该会好些),充斥着动辄数千行的函数,包...

wuhui_gdnt
2017/03/10
0
0
编译器架构--LLVM

LLVM 是 Low Level Virtual Machine (低级虚拟机)的简称,这个库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的编译期优化、链接优化、在线编译优化、...

匿名
2008/11/02
46.8K
8
LLVM 3.7.1 发布,编译器架构

LLVM 3.7.1 发布,该版本包含对上一版本的 bug 修复,这次发布不兼容 3.7.0 的 API 和ABI,但恢复了对 LLVM 3.6/3.8 API 和ABI 兼容。 更多内容请看:mailing list announcement。 LLVM 是 ...

oschina
2016/01/07
1K
6

没有更多内容

加载失败,请刷新页面

加载更多

大数据教程(7.6)shell脚本定时采集日志数据到hdfs

上一篇博客博主分享了hadoop内置rpc的使用案例,本节博主将为小伙伴们分享一个在实际生产中使用的日志搜集案例。前面的文章我们有讲到过用户点击流日志分析的流程,本节就是要完成这个分析流...

em_aaron
3分钟前
0
0
wave和pcm互转

wav->pcm pcm->wav c#代码: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using Sys......

whoisliang
5分钟前
0
0
Win10:默认的图片打开应用,打开图片时速度明显很慢的解决办法

首先,我们随便地打开一张图片。然后,点击右上角的三个小点,最后点击弹出菜单最下面的“设置”。如下图: 在“设置”中找到下面的“人物”,把它关掉就好了。 原来,默认情况下,Win 10的图...

LivingInFHL
今天
3
0
js代码激发onchange事件,兼容谷歌火狐IE

var el = document.getElementsByName('role')[0]; el.value = '3'; var evt = document.createEvent("HTMLEvents"); evt.initEvent("change", false, true); el.dispatchEvent(evt);......

我退而结网
今天
3
0
mysql客户端报错:libmysqlclient_16 not defined in file libmysqlclient.so.16

报错情况: 安装完mydumper之后(上一篇文章),登陆Mysql客户端报错:version libmysqlclient_16 not defined in file libmysqlclient.so.16 with link time reference 同样:mysql的其他客...

machogyb
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部