LLVM(简介)

历史

LLVM(low level virtual machine)起源于伊利诺伊大学的一个编译器实验项目,目前已经发展成一个集编译器和工具链为一体的商业开源项目,因此其英文名称的含义被扩大,不再仅仅是字面意思。其创始人为 Chris Lattner。LLVM项目遵循的开源许可协议是 Apache 2.0License。LLVM 从2003 年10月24 日发布第一个开源版本 LLVM1.0 以来,截止2020 年第一个季度,已经发布到LLVM10.0.0 版本,十几年间开发者社区也在不断壮大,从 2007 年起至今,每年都会举办 1-2 次 LLVM 开发者大会,在大会上有很多优秀的开发者们分享他们对于LLVM项目的一些技术问题研究。2012年LLVM获得了2012ACM软件系统奖。

最开始LLVM在项目初期,定向研究终身程序优化,后来随着项目成熟,维护编译器IP在磁盘上表示的设计成决策仍然是为了实现连接时优化,而较少关注终身优程序优化的原始想法。

最后,LLVM核心库通过放弃低级虚拟机(Low Level Virutal Machine)这个名称,正式表明成为一个平台不感兴趣,而仅仅由于历史原因,所以用LLVM这个名字,而要成为强大和实用的C/C++编译器,而不是java的竞争对手

LLVM是个啥?

经典的编译器如gcc在设计上都是提供一条龙服务的: 你不需要知道它使用的IR是什么样的,它也不会暴露中间接口来给你操作它的IR。 换句话说,从前端到后端,这些编译器的大量代码都是强耦合的

编译原理主要过程分为两个:

  • 前端把源代码翻译成中间代码IR
  • 后端把IP翻译成机器码,或者给解释器执行

LLVM的核心设计是LLVM IR
它使用的静态单赋值形式(SSA)两个重要特征:

  • 代码被组织为三地址指令
  • 它有数目不受限制的寄存器

同时作为编译器IR,用于指导核心库开发的两个LLVM IR的基本原则:

  • SAA表示和允许快速优化的无限寄存器
  • 通过将整个程序存储在磁盘IR表示中以实现更便捷的链接时优化

LLVM采用了功能划分更为明确的模块化设计。LLVM将优化的部分单独提取出来,不再将编译器的优化功能与前端或者后端的功能代码耦合在一起!
LLVM进行代码混淆保护,实际上需要改造的是优化器部分,通过编写用于代码混淆的定制的Pass来完成混淆处理,不需要对后端的Pass进行改造
在这里插入图片描述

LLVM Pass

Pass就是“遍历一遍IR,可以同时对它做一些操作”的意思
LLVM Pass分为两种类型:

  • 分析Pass:用于获取LLVM IR中的信息,例如函数的调用关系、变量的使用情况等。
  • 转换Pass:用于对LLVM IR进行修改,例如优化代码、插入代码等。

LLVM Pass可以用于各种目的,例如:

  • 代码优化:LLVM Pass可以用于提高代码的性能、减少代码的大小等。
  • 代码分析:LLVM Pass可以用于获取代码的信息,例如代码的调用关系、变量的使用情况等。
  • 代码插桩:LLVM Pass可以用于在代码中插入新的代码,例如用于调试或分析。

LLVM Pass是LLVM编译器的核心组件,是LLVM编译器的灵活性和可扩展性的基础。

以下是一些常见的LLVM Pass:

  • 死代码删除(Dead Code Elimination):删除不执行的代码。
  • 常量折叠(Constant Folding):将常量表达式折叠为常量值。
  • 寄存器分配(Register Allocation):将变量分配到寄存器中。
  • 指令重排序(Instruction Scheduling):重新安排指令的顺序,以提高性能。

用户可以根据自己的需要来编写或使用LLVM Pass。LLVM提供了丰富的API和文档,可以帮助用户快速入门。

LLVM的核心是一个库,而不是一个具体的二进制程序。 不过,LLVM这个项目本身也基于这个库实现了周边的工具, 下面列出了几个重要的命令行工具,光看名字就可以知道它们大概在做什么

  • llvm-as:把LLVM IR从人类能看懂的文本格式汇编成二进制格式。注意:此处得到的不是目标平台的机器码。
  • llvm-dis:llvm-as的逆过程,即反汇编。 不过这里的反汇编的对象是LLVM IR的二进制格式,而不是机器码。
  • opt:优化LLVM IR。输出新的LLVM IR。
  • llc:把LLVM IR编译成汇编码。需要用as进一步得到机器码。
  • lli:解释执行LLVM IR。

源代码

  1. 根目录下,最重要的就是include和lib这两个文件夹。include文件夹包含了其它项目在使用LLVM核心库时需要包含的头文件,而lib文件夹里放的就是LLVM核心库的实现。分别打开lib和include,可以看到很多文件与子文件夹。有经验的读者应该能从名字大概猜到其实现的东西。比如,lib/IR子文件夹肯定是存放了与IR相关的代码,lib/Target子文件夹肯定与生成目标平台机器码有关。又比如,include/llvm/Pass.h文件里面声明了Pass类用来给你继承去遍历、修改LLVM IR。 当然,我们现在不必知道每个模块是干什么的。 等有需要再去查看官方文档吧。
  2. 根目录下还有一个tools文件夹,这里面就存放了我上面所说的周边工具。 打开这个目录,就可以看到类似llvm-as这样的子目录。显然这就是llvm-as的实现。
    在这里插入图片描述
    在这里插入图片描述

Clang

Clang 是 LLVM 编译器工具集的前端,支持 C、C++、Objective-C 和 Objective-C++ 等编程语言。它采用了 LLVM 作为其后端,由 LLVM2.6 开始,一起发布新版本。

Clang 的目标是提供一个 GNU 编译器套装的替代品,支持了 GNU 编译器大多数的编译设置以及非官方语言的扩展。

Clang 的主要功能包括:

  • 语法分析:Clang 可以分析 C、C++、Objective-C 和 Objective-C++ 等编程语言的语法。
  • 代码生成:Clang 可以生成 LLVM 中间代码(IR)。
  • 代码优化:Clang 可以对 LLVM IR 进行优化,以提高代码的性能和可移植性。
  • 代码分析:Clang 可以对 LLVM IR 进行分析,以获取代码的信息,例如代码的调用关系、变量的使用情况等。

Clang 在许多操作系统和平台上都有可用版本,包括 macOS、Linux、Windows、iOS 和 Android。

Clang 是一个开源项目,由 LLVM 开发小组维护。

以下是 Clang 的一些优势:

  • 速度快:Clang 的编译速度比 GCC 快。
  • 体积小:Clang 的代码体积比 GCC 小。
  • 可扩展性强:Clang 支持插件式架构,可以通过编写插件来扩展 Clang 的功能。

Clang 是一个功能强大、高效的编译器,可以用于各种目的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/289123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java数据结构与算法刷题-----LeetCode746. 使用最小花费爬楼梯

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难,但它就是固定套路而已。其实动态规划只…

嵌入式系统(二)单片机基础 | 单片机特点 内部结构 最小系统 电源 晶振 复位

上一篇文章我们介绍了嵌入式系统 嵌入式系统(Embedded System)是一种特定用途的计算机系统,它通常嵌入在更大的产品或系统中,用于控制、监测或执行特定的任务。这些系统通常由硬件和软件组成,旨在满足特定的需求&…

SQL窗口函数大小详解

窗口大小 OVER 子句中的 frame_clause 选项用于指定一个滑动的窗口。窗口总是位于分区范围之内,是分区的一个子集。指定了窗口之后,分析函数不再基于分区进行计算,而是基于窗口内的数据进行计算。 指定窗口大小的语法如下: ROWS…

了解并使用django-rest-framework-jwt

一 JWT认证 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制。 Json web token (JWT), 是为了在网络应用环…

2023年12月GESP C++七级编程题转Python真题解析

七、2023年12月GESP C(Python)七级编程题 2023年12月GESP Python最高六级,但C与Python同级编程题相同。本篇引用2023年12月GESPC七级编程题,用Python实现。 【七级编程题1】 【试题名称】:商品交易 时间限制:1.0 s 内存限制&…

CMake入门教程【核心篇】引用子模块.cmake文件(include)

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「本文的内容」:CMake入门教程 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 include子模块举个例…

四、HTML 属性

属性是 HTML 元素提供的附加信息。 一、HTML 属性 HTML 元素可以设置属性属性可以在元素中添加附加信息属性一般描述于开始标签属性总是以名称/值对的形式出现&#xff0c;比如&#xff1a;name"value"。 二、 属性实例 HTML 链接由 <a> 标签定义。链接的地…

HC-05蓝牙模块--------手机与STM32通信(代码编写)(上位机配置)保姆级教程

⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩因为之前无论是电赛还是做项目&#xff0c;都用到了蓝牙模块&#xff0c;如&#xff1a;手机和stm32的通信&#xff0c;电赛中的双车通信&#xff0c;还是遥感小车的…

教育机构培训系统小程序功能清单

制作一款适合自己的教育机构培训系统小程序&#xff0c;可以为学员提供更便捷的学习体验&#xff0c;同时提高机构的教学效率。今天将详细介绍如何使用乔拓云平台制作教育机构培训系统小程序。 在浏览器搜索乔拓云&#xff0c;登录到后台&#xff0c;选择教育系统并点击进入。在…

使用MQTT.JS创建一个网页版的MQTT客户端

一、MQTT.JS介绍 MQTT.js 是一个开源的 MQTT 协议的客户端库&#xff0c;使用 JavaScript 编写&#xff0c;主要用于 Node.js 和 浏览器环境中。是JavaScript 环境下的 MQTT 客户端库。可以用于微信小程序、支付宝小程序等定制浏览器环境。 我们可以直接在HTML文件中进行调用…

静态代理、JDK动态代理、CGLIB动态代理以及JDK和CGLIB动态代理的区别

代理 什么是代理&#xff1f;两个设计原则三要素 静态代理静态代理的实现定义接口-定义行为静态代理 -> 目标角色静态代理-> 代理角色静态代理测试 特点 JDK动态代理newProxyInstance获取代理对象通过代理对象实现目标对象的功能特点 Java动态代理类中的invoke是怎么调用…

P8 RV1126推流 —— 摄像头和咪头模块初始化

前言 从本章开始我们将要学习嵌入式音视频的学习了 &#xff0c;使用的瑞芯微的开发板 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Linux C应用编程&#xff08;概念类&#xff09;_C…

对偶问题的基本性质

写于&#xff1a;2024年1月3日晚 修改于&#xff1a; 原规划与对偶规划 原规划对偶规划 max ⁡ z C T X s.t. { A X ≤ b , 其中 X ( m ∗ 1 ) X ≥ 0 \begin{aligned} & \max \mathrm{z}\mathbf{C}^T \mathbf{X} \\ & \text { s.t. }\left\{\begin{array}{l}\mat…

RFID在物流、供应链管理、工业自动化等领域的广泛应用

随着物联网技术的不断发展&#xff0c;RFID&#xff08;无线射频识别&#xff09;技术作为一种自动识别和跟踪技术&#xff0c;在物流、供应链管理、工业自动化等领域得到了广泛应用。本文将介绍RFID解决方案及其应用场景。 一、RFID技术概述 RFID是一种通过无线电波通信&…

Apache的配置与应用

目录 1、Apache简介 2、Apache连接保持 3、Apache的访问控制 3.1、客户机地址限制 3.2、用户授权限制 &#xff08;1&#xff09;创建用户认证数据文件 &#xff08;2&#xff09;添加用户授权配置 &#xff08;3&#xff09;验证用户访问授权 4、Apache日志分割 4…

ALSA学习(5)——ASoC架构中的Machine

参考博客&#xff1a;https://blog.csdn.net/DroidPhone/article/details/7231605 &#xff08;以下内容皆为原博客转载&#xff09; 文章目录 一、注册Platform Device二、注册Platform Driver三、初始化入口soc_probe() 一、注册Platform Device ASoC把声卡注册为Platform …

FreeRTOS——计数型信号量知识总结及实战

1计数型信号量概念 1&#xff09;计数型信号量相当于队列长度大于1 的队列&#xff0c;因此计数型信号量能够容纳多个资源 2&#xff09;适用场景&#xff1a; 事件计数&#xff1a; 当每次事件发生后&#xff0c;在事件处理函数中释放计数型信号量&#xff08;计数值1&#x…

shell编程二

shell 脚本规范 shell脚本文件需要以.sh结尾 第一个原因&#xff0c;让别人认的这个是shell脚本&#xff0c;sh后缀编辑时有高亮显示。 拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本 ​ # 执行脚本方式 1、 sh 脚本.sh 2、 bash 脚本.sh 3、 ./脚本.sh # 需要执行权…

【C语言】数组

㊙️小明博客主页&#xff1a;➡️ 敲键盘的小明 ㊙️ ✅关注小明了解更多知识☝️ 文章目录 前言一、什么是数组&#xff1f;二、一维数组的创建和初始化2.1 一维数组的创建2.2 一维数组的初始化2.3 一维数组的使用3.3 一维数组的存储 三、二维数组的创建和初始化3.1 二维数组…

每日一练:LeeCode-503. 下一个更大元素 II (中)【单调栈】

本文是力扣LeeCode-503. 下一个更大元素 II 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个…
最新文章