首页 > 其他分享 >实现“代码可视化”需要了解的前置知识-编译器中端

实现“代码可视化”需要了解的前置知识-编译器中端

时间:2024-05-21 10:41:41浏览次数:13  
标签:LLVM int 代码 IR 编译器 可视化 优化 中端

1. 前言

前文实现“代码可视化”需要了解的前置知识-编译器前端介绍了编译器前端知识并附带了小练习,本文将继续介绍编译器中端相关的知识,还是概念+练习的学习方式。中间代码是用来进行程序分析和实现代码可视化的关键数据,了解其生成和优化方式能更好的帮助我们理解程序的执行逻辑,希望大家阅读本文后有所收获。

2. 编译器(Compiler)

中端部分主要包含的功能有“生成中间代码”和“中间代码优化”。

 


 

2.1 编译器工作步骤

 


 

2.2 编译器中端

2.2.1 中间代码生成

2.2.1.1 为什么需要中间代码?

编译器很难通过一次处理就得到最优的目标代码,实际的编译器大多组织为一连串的处理趟,每一趟处理的结果又作为下一趟的输入持续的运行。随着编译器不断推导有关被编译代码的知识,它必须将这些信息从一趟传递到另一趟。因此,这些能推导出有关程序全部事实的信息需要一种表示方式,称之为中间代码或中间表示(intermediate representation),简称IR。

 


 

广义角度可以将源码到目标代码之间的表达形式都称之为中间代码。其目的是为了解耦编译器前端和后端部分,作为高级语言和目标机器语言之间的桥梁,不依赖于特定的源语言或目标机器使得一些代码优化动作能够复用。与高级语言相比,IR 丢弃了大部分高级语言的语法特征和语义特征,比如循环语句、if 语句、作用域、面向对象等等,它更像高层次的汇编语言;而相比真正的汇编语言,它又不会有那么多琐碎的、与具体硬件相关的细节。

 


 

如果源语言语法结构较为简单,编译器可能会用唯一的IR,但如果源语言语法结构比较复杂,则在转换为目标语言的过程中可能会使用了一系列的IR,并通过转换进行大量的优化操作。

 


 

由于不同语言编译器中IR差异较大,本文后续内容对于概念部分只做点到即止的阐述,有兴趣的同学可以自行查阅资料,增加了LLVM的中间代码实操用来加深理解。LLVM 是一个开源的编译器基础设施项目,主要聚焦于编译器的后端功能(代码生成、代码优化、JIT……),其在业界被广泛应用,很多语言都是基于它实现的,更多信息可以查看官网

 


 

2.2.1.2 中间代码分类

按照与源代码接近程度可以分为:

高级IR:更接近源代码,保留了更多的源代码层面的信息,如数据类型、控制结构等。通常用于编译器前端的语义分析和初步优化阶段。例如:AST等; •中级IR:开始脱离源代码的具体语法,引入更多与机器无关的优化。通常用于进行编译器的主要优化,如循环优化、常量传播、死代码消除等。例如:TAC等; •低级IR:接近目标机器代码,更多地反映了目标平台的具体特性,如寄存器、指令集等。用于编译器后端的优化,特别是那些与目标机器密切相关的优化,如寄存器分配、指令选择和调度。

根据其结构和表现形式可以分为:

图IR: 将编译器生成的信息保存在图中,通过图结构来表示程序的各种属性。图IR非常适合表示并分析程序的复杂结构,如循环、分支等。例如:AST、CFG和DFG等; •线性IR: 以线性的方式表示程序,通常是一系列的指令或语句。不像图IR那样直观地表示控制流或数据流,但对于某些分析和转换来说更简单、直接,常用于编译器的早期阶段,进行简化的分析和转换。例如:TAC、SSA等; •混合IR: 结合了图IR和线性IR的特点,尝试兼顾两者的优势。一种常见的混合表示为使用线性IR来表示无循环代码的块,使用图来表示这些块之间的控制流。混合IR旨在提供足够的灵活性来支持各种编译阶段的需要,从而使编译器能够有效地执行复杂的优化和分析。

了解了基本的分类,下面介绍几种常见的中间表示方式,并针对表达式A进行不同形式的呈现:

// 表达式A
a=(-b+c*d)+c*d

① 抽象语法树(Abstract Syntax Tree, AST)

通过编译器前端生成的抽象语法树也算是高级IR和图IR,它保留了源代码的语法结构,如表达式、语句、函数定义等。这里就不再赘述生成过程,如果忘记了相关知识可以再复习一下前文。表达式A对应的AST为:

 


 

② 有向无环图(Directed Acyclic Graph,DAG)

有向无环图是在树结构的基础上,消除了冗余的子树。其结点可以有多个父结点,相同子树可以被重用,可以理解为是一种具有共享机制的AST。表达式A对应的DAG为:

 


 

③ 三地址代码(Three-Address Code, TAC)

三地址代码是中级IR和线性IR,它是一种接近于汇编语言但又保持了高级语言特征的代码形式。这种形式的IR特别适合于执行和表示各种编译时优化。在三地址代码中,每条指令通常涉及到两个操作数(y、z)和一个结果(x),指令的一般形式可以是:

x = y op z

其中,op 是一个二元运算符,y 和 z 是操作数,可以是常量、变量或者临时变量,x 是存放结果的变量或临时变量。三地址代码也支持一元运算符,这种情况下指令的形式为:

x = op y

常用的三地址代码有:

 指令形式备注
赋值指令 x = y op z x = op y op为运算符
复制指令 x = y  
条件跳转 if x relop y goto n relop为关系运算符
非条件跳转 goto n 跳转到地址n的指令
参数传递 param x 将x设置为参数
过程调用 call p,n p为过程的名字,n为过程的参数的个数
过程返回 return x  
数组引用 x=y[i] i为数组的偏移地址,而不是下标
数组赋值 x[i]=y  
地址及指针操作 x=&y、x=*y*x=y  

表达式A对应的TAC为(可以通过遍历AST生成TAC):

 


 

④ 静态单赋值形式(Static Single Assignment, SSA)

静态单赋值形式也是一种线性IR,它和三地址代码的主要区别在所有赋值指令都是对不同名字的变量的赋值。每个变量很确定地只会被定义一次,然后可以多次使用。这种特点使得基于SSA更容易做数据流分析,而数据流分析又是很多代码优化技术的基础,所以几乎所有语言的编译器、解释器或虚拟机中都使用了SSA。下图展示了两种表示方式的区别:

 


 

另外,表达式A生成的TAC和SSA是一样的,大家不妨验证一下是否符合SSA的特性

标签:LLVM,int,代码,IR,编译器,可视化,优化,中端
From: https://www.cnblogs.com/Jcloud/p/18203471

相关文章

  • 多状态马尔可夫链、生存分析心脏同种异体移植血管病变(CAV)数据可视化|附数据代码
    原文链接:https://tecdat.cn/?p=36216原文出处:拓端数据部落公众号临床研究和医疗经济学研究中客户经常关注于评估患者在疾病从一种状态发展到另一种状态时的生存预后。标准生存模型仅直接模拟两种状态:存活和死亡。多状态模型允许直接模拟疾病进程,在这些过程中,患者在随机的时间间......
  • R语言空气污染数据的地理空间可视化和分析:颗粒物2.5(PM2.5)和空气质量指数(AQI)|附代码数
    原文链接:http://tecdat.cn/?p=23800最近我们被客户要求撰写关于空气污染数据的研究报告,包括一些图形和统计输出。由于空气污染对公众健康的不利影响,人们一直非常关注。世界各国的环境部门都通过各种方法(例如地面观测网络)来监测和评估空气污染问题介绍全球的地面站及时测量了许......
  • R语言逻辑回归、决策树、随机森林、神经网络预测患者心脏病数据混淆矩阵可视化
    全文链接:https://tecdat.cn/?p=33760原文出处:拓端数据部落公众号概述:众所周知,心脏疾病是目前全球最主要的死因。开发一个能够预测患者心脏疾病存在的计算系统将显著降低死亡率并大幅降低医疗保健成本。机器学习在全球许多领域中被广泛应用,尤其在医疗行业中越来越受欢迎。机器......
  • 【开源】2024最新python豆瓣电影数据爬虫+可视化分析项目
    项目介绍【开源】项目基于python+pandas+flask+mysql等技术实现豆瓣电影数据获取及可视化分析展示,觉得有用的朋友可以来个一键三连,感谢!!!项目演示[video(video-C9B87WwE-1716106102936)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=1204518067)(image-https......
  • 前端使用 Konva 实现可视化设计器(11)- 对齐效果
    这一章补充一个效果,在多选的情况下,对目标进行对齐。基于多选整体区域对齐的基础上,还支持基于其中一个节点进行对齐。请大家动动小手,给我一个免费的Star吧~大家如果发现了Bug,欢迎来提Issue哟~github源码gitee源码示例地址基于整体的对齐垂直居中水平居中左对齐......
  • 一文彻底整明白,基于Ollama工具的LLM大语言模型Web可视化对话机器人部署指南
    在上一篇博文中,我们在本地部署了Llama38B参数大模型,并用Python写了一个控制台对话客户端,基本能愉快的与Llama大模型对话聊天了。但控制台总归太技术化,体验不是很友好,我们希望能有个类似ChatGPT那样的Web聊天对话界面,本博文就安排起来……上一篇Llama38B大模型部署......
  • R语言CART决策树、随机森林、chaid树预测母婴电商平台用户寿命、流失可视化
    全文链接:http://tecdat.cn/?p=31644原文出处:拓端数据部落公众号借着二胎政策的开放与家庭消费升级的东风,母婴市场迎来了生机盎然的春天,尤其是母婴电商行业,近年来发展迅猛。用户获取和流失是一对相对概念,就好比一个水池,有进口,也有出口。我们不能只关心进口的进水速率,却忽略了出水......
  • 智慧园区可视化大屏设计
    首先,让我们来了解一下什么是智慧园区可视化大屏。简单来说,它是一种将复杂的数据通过图形化的方式展示出来的技术。这种技术的出现,让我们可以更直观、更清晰地理解数据,从而做出更准确的决策。     那么,为什么我们要讨论智慧园区可视化大屏设计呢?因为,它不仅仅是一种......
  • 数据分享|SAS与eviews用ARIMA模型对我国大豆产量时间序列预测、稳定性、白噪声检验可
    全文链接:http://tecdat.cn/?p=31480最近我们被客户要求撰写关于ARIMA的研究报告,包括一些图形和统计输出。我国以前一直以来都是世界上大豆生产的第一大国。但由于各国的日益强大,导致我国豆种植面积和产量持续缩减。因此,预测我国的大豆产量对中国未来的经济发展有着极其重要的作......
  • 达梦 本地可视化建表
     前言:达梦的远程与本地是不可以与MYSQL的可视化Navicat一样的。连接远程服务器的达梦是不可以在可视化进行操作的。 1.新建表空间新建本地连接,本地的表空间再新建表空间,在常规进行添加。(常规 一般要添加两个,自动扩充要从默认改为打开)文件路径在本地DAME......