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.mzph.cn/news/24528.shtml

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

相关文章

关于HIVE的分区与分桶

1.分区 1.概念 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区&#xff0c;这样的查询效率会提高很多 个人理解白话:按表中或者自定义的一个列,对数据进…

C#中XML文档与Treeview控件操作的数据同步

在前文《C#使用XML和Treeview结合实现复杂数据采集功能》中&#xff0c;使用Treeview展示了XML的数据&#xff0c;问题是如果在Treeview上进行了操作&#xff0c;怎样同步更改XML数据的内容呢&#xff1f; 这个问题看似简单&#xff0c;实现起来有一点小麻烦。 要实现的操作功能…

C语言假期作业 DAY 13

一、选择题 1、如果 x2014 &#xff0c;下面函数的返回值是&#xff08; &#xff09; int fun(unsigned int x) { int n 0; while(x 1) { n; x x | (x 1); } return n; } A: 20 B: 21 C: 23 D 25 答案解析 正确答案&#xff1a;C 这个作用是对整型中0的个数进行统计&…

K8s中的Secret

Secret作用&#xff1a;加密数据存在etcd里面&#xff0c;让pod容器以挂载Volume方式进行访问。场景&#xff1a;凭据

规划路线(微信小程序、H5)

//地图getLocationDian(e1, e2) {console.log(e1, e2);let self this;self.xx1 [];self.xx2 [];self.points [];// self.markers[]console.log(self.markers, >marks);// self.$jsonp(url, data).then(re > {// var coors re.result.routes[0].polyline;// for (v…

【Python】Locust持续优化:InfluxDB与Grafana实现数据持久化与可视化分析

目录 前言 influxDB 安装运行InfluxDB 用Python 上报数据到influxdb ocust 数据写入到 influx Locust的生命周期 上报数据 优化升级 配置Grafana 总结 资料获取方法 前言 在进行性能测试时&#xff0c;我们需要对测试结果进行监控和分析&#xff0c;以便于及时发现问…

HTML+CSS+JavaScript:渲染电商站购物车页面

一、需求 根据下图渲染购物车页面 二、代码素材 以下是缺失JS部分的代码&#xff0c;感兴趣的小伙伴可以先自己试着写一写 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatib…

政务云建设与应用解决方案[42页PPT]

导读&#xff1a;原文《政务云建设与应用解决方案[42页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需获取完…

ELF文件格式解析

ELF(Executable and Linkable Format) 即可执行可链接文件格式&#xff0c;是目前操作系统上最常见的可执行文件格式。不同系统的目标文件不一样&#xff0c;Windows是PE&#xff08;Portable Executable&#xff09;&#xff0c;linux是ELF&#xff08;Executable Linkable Fo…

【SpringCloud】RabbitMQ基础

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;…

vue2-diff算法

1、diff算法是什么&#xff1f; diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点&#xff1a; 比较只会在同层级进行&#xff0c;不会跨层级进行。 在diff比较的过程中&#xff0c;循环从两边向中间比较。 diff算法在很多场景中都有应用&#xff0c;在vue中&…

Jmeter(一) - 从入门到精通 - 环境搭建(详解教程)

1.JMeter 介绍 Apache JMeter是100%纯JAVA桌面应用程序&#xff0c;被设计为用于测试客户端/服务端结构的软件(例如web应用程序)。它可以用来测试静态和动态资源的性能&#xff0c;例如&#xff1a;静态文件&#xff0c;Java Servlet,CGI Scripts,Java Object,数据库和FTP服务器…

Hadoop学习:深入解析MapReduce的大数据魔力(二)

Hadoop学习&#xff1a;深入解析MapReduce的大数据魔力&#xff08;二&#xff09; 3.3 Shuffle 机制3.3.1 Shuffle 机制3.3.2 Partition 分区3.3.3 Partition 分区案例实操3.3.4 WritableComparable 排序3.3.5 Combiner 合并 3.4 OutputFormat 数据输出3.4.1 OutputFormat 接口…

HttpServletRequest和HttpServletResponse的获取与使用

相关笔记&#xff1a;【JavaWeb之Servlet】 文章目录 1、Servlet复习2、HttpServletRequest的使用3、HttpServletResponse的使用4、获取HttpServletRequest和HttpServletResponse 1、Servlet复习 Servlet是JavaWeb的三大组件之一&#xff1a; ServletFilter 过滤器Listener 监…

医学图像处理

医学图像处理 opencv批量分片高像素图像病理图像色彩特征提取基于 imgaug、skimage 实现色彩增强基于 Cycle-GAN 完成染色标准化 病理图像细微特征提取自动数据标注分类场景下的医学图像分析分割场景下的医学图像分析检测场景下的医学图像分析 , i ] k 8 < * I opencv批量…

4.DNS和负载均衡

文章目录 coreDNS概念部署croeDNS测试 kubernetes多master集群结构master节点部署 负载均衡配置部署nginx做四层反向代理安装高可用 keepalivednginx监控脚本修改k8s中组件的配置文件 coreDNS 概念 coreDNS是kubernetes的默认DNS实现。可以为集群中的service资源创建一个资源名…

PyTorch中加载模型权重 A匹配B|A不匹配B

在做深度学习项目时&#xff0c;从头训练一个模型是需要大量时间和算力的&#xff0c;我们通常采用加载预训练权重的方法&#xff0c;而我们往往面临以下几种情况&#xff1a; 未修改网络&#xff0c;A与B一致 很简单&#xff0c;直接.load_state_dict() net ANet(num_cla…

Java课设--学生信息管理系统(例1)

文章目录 前提一、运行效果二、Text实现类三、Manage选择类四、StudentWay学生方法类五、StudnetSql数据库类 前题 例1为无使用GUI图形界面&#xff0c;例2使用GUI图形界面&#xff01; 首先自己的JDBC驱动已经接好了&#xff0c;连接自己的数据库没有问题。连接数据库可以看…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(33)-Fiddler如何抓取WebSocket数据包

1.简介 本来打算再写一篇这个系列的文章也要和小伙伴或者童鞋们说再见了&#xff0c;可是有人留言问WebSocket包和小程序的包不会抓&#xff0c;那就关于这两个知识点宏哥就再水两篇文章。 2.什么是Socket&#xff1f; 在计算机通信领域&#xff0c;socket 被翻译为“套接字…

物联网||不一样的点灯实验(2)|通过使用CMSIS库函数实现点灯实验-学习笔记(12)

文章目录 通过使用CMSIS库函数实现点灯实验1 如何使用CMIS库2 如何利用CMSIS库操作IO 两种实现方法的比较课后作业:完整代码&#xff1a;LED.C:test.c:led.h:systick.h:systick.c: 通过使用CMSIS库函数实现点灯实验 1 如何使用CMIS库 #####如何使用此驱动#####[. .](#)启用GPI…