LLVM笔记1

参考:https://www.bilibili.com/video/BV1D84y1y73v/?share_source=copy_web&vd_source=fc187607fc6ec6bbd2c74a3d0d7484cf

文章目录

  • 零、入门名词解释
    • 1. Compiler & Interpreter
    • 2. AOT静态编译和JIT动态解释的编译方式
    • 3. Pass
    • 4. Intermediate Representations中间表达
    • 5. 编译器基本构成
  • 一、GCC编译流程
  • 二、LLVM编译技术
    • 1. LLVM设计架构
    • 2. LLVM IR
      • 2.1 IR语法
      • 2.2 IR三种表达形式
      • 2.3 IR内存模型
    • 3. LLVM前端
      • 3.1 词法分析
      • 3.2 语法分析
      • 3.3 语义分析
    • 4. LLVM优化
      • 4.1 发现Pass
      • 4.2 Pass依赖
      • 4.3 Pass API
    • 5. LLVM后端
    • 5.1 指令选择
    • 5.2 指令调度
    • 5.3 寄存器分配
    • 5.4 指令调度
    • 5.5 代码输出
  • 发展


零、入门名词解释

1. Compiler & Interpreter

将程序从高级语言翻译到机器语言,得到一个可运行的文件。
在这里插入图片描述
在这里插入图片描述

2. AOT静态编译和JIT动态解释的编译方式

在这里插入图片描述

3. Pass

对源程序的一次完整扫描或处理。从高级语言到低级语言或者IR会经过几次Pass。比如下图第一个Pass是词法分析、语法分析、语义分析(图片里中间代码生成拼错了)。
在这里插入图片描述

4. Intermediate Representations中间表达

可以是数据结构或者定义好的代码,能让编译器或者虚拟机表达源码就行。

5. 编译器基本构成

  • 前端:词法语法分析,将源代码转化为抽象语法树。
  • 优化:对前端得到的IR优化,使得更高效。
  • 后端:将优化的IR转化为针对各自平台的机器代码。比如X86、ARM、GPU上执行的机器码是不同的。
    在这里插入图片描述

一、GCC编译流程

  • 预处理(前端):读入源代码,响应预处理指令和替换宏定义,删除程序中的注释和多余空白符。会把引用的头文件和自己写的hello.c文件都放在hello.i文件中。
  • 编译(优化):语法分析和词法分析,以及大量优化。hello.s中都是汇编指令。
  • 汇编(后端):则是将汇编指令转为机器语言。
  • 链接(后端):链接程序用到的目标文件、各种依赖的库文件,生成可执行文件,以二进制形式存储在磁盘中。
    在这里插入图片描述

二、LLVM编译技术

1. LLVM设计架构

利用IR做中转,将前端和优化和后端分离开。不同于GCC的前后端没有解耦,LLVM增加一种新的语言时只用实现一个新的编译前端,优化和后端都能复用。

clang -E -c hello.c -o hello.i
clang -emit-llvm hello.c -S -o hello.ll #这里是导出为IR模式
llc hello.ll -o hello.s #这里导出的是汇编语言了
clang hello.s -o hello #这里得到可执行的二进制文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2. LLVM IR

2.1 IR语法

;表示注释
@全局变量开头
%局部变量开头
alloca在函数栈中分配内存
store写入
load读取
i32 32位4字节
align字节对齐(计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的 倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。)
在这里插入图片描述

  • IR假设寄存器数量无限。
  • 指令都是三地址形式,操作码OP 第一操作数地址A1 第二操作数地址A2 结果地址A3
  • 不使用固定的命名寄存器,都是用%字符命名临时寄存器。

2.2 IR三种表达形式

这三种中间格式是完全等价的:

  • 在内存中的编译中间语言(无法通过文件的形式得到的指令类等)
  • 在硬盘上存储的二进制中间语言( 格式为.bc )
  • 人类可读的代码语言(格式为.Il )

2.3 IR内存模型

如果在编译器的优化层对LLVM的IR进行操作,写一个定制的优化pass,就需要了解LLVM IR内存模型。

● LLVM IR文件的基本单位称为module;
● 一个module中可以拥有多个顶层实体,比如function和global variable;
● 一个function define中至少有一个basicblock(就是花括号);
● 每个basicblock中有若干instruction ,并且都以terminator instruction(写作ret,就是return的意思)结尾。

void test( int a, int b){int c=a*b + 100;
}
1 ; Function Attrs: noinline nounwind optnone ssp uwtable
2 define void @test(i32, i32) #2 { ;有个全局函数@test (a,b)
3 %3 = alloca 132,align 4 ;局部变量C
4 %4 = alloca i32,align 4 ;局部变量d
5 %5 = alloca i32, align 4 ;局部变量e
6 store i32 %0, i32*%3,align 4 ;%0赋值给3C=a
7 store i32%1,i32*%4,align 4 ;%1赋值给%4d=b
8 %6=load i32, i32*%3, align 4 ;读取%3 ,赋值给%6就是函数参数a
9 %7=load i32, i32* %4 , align 4 ;读取%4 ,赋值给%7就是函数参数b
10 %8=mul nsw i32%6, %7 ;a*b
11 %9=add nsw i32%8, 100 ;a*b+100
12 store i32%9, i32*%5, align 4 ;参数%9赋值给%5 e ===>就是转换前函数写的int c变量
ret void

3. LLVM前端

3.1 词法分析

前端的第一个步骤处理源代码的文本输入,将语言结构分解为一组单词和标记,去除注释、空白、制表符等。每个单词或者标记必须属于语言子集,语言的保留字被变换为编译器内部表示

3.2 语法分析

分组标记以形成表达式、语句、函数体等。检查-组标记是否有意义 ,考虑代码物理布局,未分析代码的意思,就像英语中的语法分析,不关心你说了什么,只考虑句子是否正确,并输出语法树( AST )。
在这里插入图片描述

3.3 语义分析

借助符号表检验代码没有违背语言类型系统。符号表存储标识符和其各自的类型之间的映射,以及其它内容。类型检查的一-种直觉的方法是,在解析之后,遍历AST的同时从符号表收集关于类型的信息。

4. LLVM优化

4.1 发现Pass

优化通常由分析Pass和转换Pass组成:

  • 分析Pass :负责发掘性质和优化机会;
  • 转换Pass :生成必需的数据结构,后续为后者所用;

4.2 Pass依赖

在转换Pass和分析Pass之间,有两种主要的依赖类型:

  • 显式依赖:转换Pass需要一种分析,则Pass管理器自动地安排它所依赖的分析Pass在它之前运行;
DominatorTree &DT = getAnalysis<DominatorTree>(Func);
  • 隐式依赖:转换或者分析Pass要求IR代码运用特定表达式。需要手动地以正确的顺序把这个Pass加到Pass队列中,通过命令行工具( clang或者opt )或者Pass管理器。

4.3 Pass API

Pass类是实现优化的主要资源。然而,我们从不直接使用它,而是通过清楚的子类使用它。当实现一个Pass时,你应该选择适合你的Pass的最佳粒度,适合此粒度的最佳子类,例如基于函数、模块、循环、强联通区域,等等。常见的这些子类如下:
● ModulePass (一个模块)
● FunctionPass(一个函数)
● BasicBlockPass (某几条指令)

5. LLVM后端

也是由多个Pass链接,分为必要Pass和非必要Pass,下面介绍一些必要Pass

5.1 指令选择

  • 内存中LLVM IR变换为目标特定SelectionDAG节点;
  • DAG有向无环图,IR变成图后表示单一的一个计算节点,图的节点是具体执行的指令,边是数据流依赖关系。。每个DAG能够表示单一基本块的计算。

5.2 指令调度

第1次指令调度( Instruction Scheduling ) ,也称为前寄存器分配(RA)调度。
●对指令排序,同时尝试发现尽可能多的指令层次的并行;
●然后指令被变换为MachineInstr三地址表示。

5.3 寄存器分配

LLVM IR寄存器集是无限的,这个性质一直保持着,直到寄存器分配( Register Allocation )
●寄存器分配将无限的虚拟寄存器引用转换为有限的目标特定的寄存器集;
●寄存器不够时挤出( spill )到内存。

5.4 指令调度

第2次指令调度,也称为后寄存器分配(RA)调度。
●此时可获得真实的寄存器信息,某些类型寄存器存在延迟,它们可被用以改进指令顺序。

5.5 代码输出

  • 代码输出阶段将指令从MachineInstr表示变换为MCInst实例;
  • 新的表示更适合汇编器和链接器,可以输出汇编代码或者输出二进制块特定目标代码格式。

发展

XLA (加速线性代数)是一种针对特定领域的线性代数编译器。

Julia面向科学计算的高性能动态编程语言,使用LLVM JIT编译。LLVM JIT编译器通常不断地分析正在执行的代码,并且识别代码的一部分 ,使得从编译中获得的性能加速超过编译该代码的性能开销。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node.js的优点

提示&#xff1a;node.js的优点 文章目录 一、什么是node.js二、node.js的特性 一、什么是node.js 提示&#xff1a;什么是node.js? Node.js发布于2009年5月&#xff0c;由Ryan Dahl开发&#xff0c;是一个基于ChromeV8引擎的JavaScript运行环境&#xff0c;使用了一个事件驱…

python可以做哪些小工具,python可以做什么小游戏

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python可以做什么好玩的&#xff0c;python可以做什么小游戏&#xff0c;今天让我们一起来看看吧&#xff01; 最近有几个友友问我说有没有比较好玩的Python小项目来练手&#xff0c;于是我找了几个比较有意思的给他们&…

数学建模-爬虫系统学习

尚硅谷Python爬虫教程小白零基础速通&#xff08;含python基础爬虫案例&#xff09; 内容包括&#xff1a;Python基础、Urllib、解析&#xff08;xpath、jsonpath、beautiful&#xff09;、requests、selenium、Scrapy框架 python基础 进阶&#xff08;字符串 列表 元组 字典…

IntelliJ IDEA 2023.2社区版插件汇总

参考插件帝&#xff1a;https://gitee.com/zhengqingya/java-developer-document 突发小技巧&#xff1a;使用插件时要注意插件的版本兼容性&#xff0c;并根据自己的实际需求选择合适的插件。同时&#xff0c;不要过度依赖插件&#xff0c;保持简洁和高效的开发环境才是最重要…

linux 安装FTP

检查是否已经安装 $] rpm -qa |grep vsftpd vsftpd-3.0.2-29.el7_9.x86_64出现 vsftpd 信息表示已经安装&#xff0c;无需再次安装 yum安装 $] yum -y install vsftpd此命令需要root执行或有sudo权限的账号执行 /etc/vsftpd 目录 ftpusers # 禁用账号列表 user_list # 账号列…

C++类和对象入门(下)

C类和对象入门 1. Static成员1.1 Static成员的概念2.2 Static成员的特性 2.友元2.1 友元函数2.2 友元函数的特性2.3 友元类 3. 内部类3.1 内部类的概念和特性 4. 匿名对象5. 再次理解类和对象 1. Static成员 1.1 Static成员的概念 声明为static的类成员称为类的静态成员&…

Git基础知识:常见功能和命令行

文章目录 1.Git介绍2.安装配置2.1 查看配置信息 3.文件管理3.1 创建仓库3.2 版本回退3.3 工作流程3.4 撤销修改3.5 删除文件 4.远程仓库4.1 连接远程库4.2 本地上传至远程4.3 从远程库克隆到本地 5.分支管理5.1 创建分支5.2 删除分支5.3 合并分支解决冲突 参考&#xff1a; Git…

Vue前端框架入门

文章目录 Vue快速入门Vue指令生命周期 Vue 经过一小段时间学习 我认为vue就是在原js上进行的一个加强 简化JS中的DOM操作 vue是分两个层的 一个叫做视图层(View)&#xff0c;你可以理解为展现出来的前端页面 一个叫数据模型层(Model),包含数据和一些数据的处理方法 MVVM就是实…

Mybatis 实体类属性名和表中字段名不一致怎么处理

一. 前言 最近耀哥有学生出去面试&#xff0c;被问到 “Mybatis实体类的属性名和表中的字段名不一致该怎么处理&#xff1f;”&#xff0c;这其实是一个很经典的面试题&#xff0c;接下来耀哥就为大家详细解析一下这道面试题。 二. 分析 2.1 实体类和字段名不一致所带来的后果…

汽车智能化再掀新热潮!「中央计算架构」进入规模量产周期

中央计算区域控制的新一代整车电子架构&#xff0c;已经成为车企继电动化、智能化&#xff08;功能上车&#xff09;之后&#xff0c;新一轮竞争的焦点。 如果说智能化的1.0阶段&#xff0c;是智能驾驶智能座舱的争夺战&#xff1b;那么&#xff0c;即将进入的2.0阶段&#xff…

postman----传参格式(json格式、表单格式)

本文主要讲解postman使用post请求方法的2中传参方式&#xff1a;json格式、表单格式 首先了解下&#xff0c;postman进行接口测试&#xff0c;必须条件是&#xff1a; ♥请求地址 ♥请求协议 ♥请求方式 ♥请求头 ♥参数 json格式 先看一下接口文档&#xff0c;根据接口文档&…

测试人员简单使用Jenkins

一、测试人员使用jenkins干什么&#xff1f; 部署测试环境 二、相关配置说明 一般由开发人员进行具体配置 1.Repository URL&#xff1a;填写git地址 2.填写开发分支&#xff0c;测试人员可通过相应分支进行测试环境的构建部署 当多个版本并行时&#xff0c;开发人员可以通过…

【Liux下6818开发板(ARM)】触摸屏

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

Unity数字可视化学校_昼夜(二)

1、时间设置&#xff1a; 2、新建夜晚 3、新建侧置球&#xff08;BOX&#xff09;,测试灯光强度 降低亮度 色调&#xff1a;冷色调 4、自发光 新建shader 灯光控制 道路线&#xff1a; 建筑&#xff1a; 夜晚加灯光&#xff1a; 玻璃&#xff1a; 加大灯光数量&#xff1a; 边缘…

AI量化模型预测——baseline学习笔记

一、赛题理解 1. 赛题名称 AI量化模型预测 2. 赛题理解 本赛事是一个量化金融挑战&#xff0c;旨在通过大数据与机器学习的方法&#xff0c;使用给定的训练集和测试集数据&#xff0c;预测未来中间价的移动方向。参赛者需要理解市场行为的原理&#xff0c;创建量化策略&#…

【java安全】无Commons-Collections的Shiro550反序列化利用

文章目录 【java安全】无Commons-Collections的Shiro550反序列化利用Shiro550利用的难点CommonsBeanutils1是否可以Shiro中&#xff1f;什么是serialVersionUID&#xff1f;W 无依赖的Shiro反序列化利用链POC 【java安全】无Commons-Collections的Shiro550反序列化利用 Shiro5…

『HarmonyOS』万物互联,分布式操作系统

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位喜欢写作&#xff0c;计科专业大二菜鸟 &#x1f3e1;个人主页&#xff1a;starry陆离 &#x1f552;首发日期&#xff1a;2022年7月5日星期二 &#x1f30c;上期文章&#xff1a;『首期文章』 &#x1f4da;订阅专栏&…

从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试是对系统…

将word每页页眉单独设置

在进行论文排版的时候&#xff0c;总是会出现页眉的页码设置问题&#xff0c;比如出现奇数或偶数页码一致&#xff0c;尝试将前面页码改掉&#xff0c;后面再修改前面也进行了变动&#xff0c;将每页页眉单独设置&#xff1a; &#xff08;1&#xff09;在第一页的最后一行输入…

【雕爷学编程】MicroPython动手做(29)——物联网之SIoT

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…