寄存器分配:图着色算法

寄存器分配:图着色算法

  • 背景
  • 活跃分析
  • 寄存器冲突图
  • 图着色算法
  • 溢出

背景

在编译器的中间表示中,一般会设定虚拟寄存器有无限多个(方便优化),而真实的物理寄存器是有限的,因而编译器后端在将中间表示翻译成目标指令集的时候会进行寄存器分配,也就是将无限的虚拟寄存器映射到有限的物理寄存器上。例如:

a := c + d
e := a + b
f := e - 1

a + ba的寄存器可以被复用,e - 1e的寄存器可以被复用,因而aef可以分配相同的寄存器。

r1 := r2 + r3
r1 := r1 + r4
r1 := r1 - 1

如果两个两个临时变量t1t2在不同的程序点只有一个是活跃的,则t1t2可以分配相同的物理寄存器。否则,如果t1t2如果同时活跃,则不能分配相同的物理寄存器。

接下来介绍图着色的寄存器分配算法。图着色算法首先要进行活跃分析,得到冲突图,然后通过对冲突图进行着色来解决寄存器分配问题。

活跃分析

变量的活跃分析采用数据流分析的方法,具体可以参阅南京大学的静态分析课程。这里直接给出活跃分析结果:

寄存器冲突图

活跃分析会得到每个程序点同时活跃的临时变量的集合。对于每一个集合(一个程序点)中每一对临时变量形成一条边,并将这些边加入到冲突图中。对程序中每个程序点的集合重复上述过程便形成寄存器冲突图(RIG, register interference graph)。

冲突中,顶点表示临时变量,边用于模拟两个临时变量在相同的程序点同时活跃。冲突图中每两个相连的变量不能分配相同的寄存器,例如ac

寄存器分配的问题就可以转换为冲突图图着色问题。图着色是给图的每个顶点进行着色,并且相连的顶点需要着不同的颜色。图的k可着色表示可以用k个颜色对图进行着色。假设物理寄存器个数为k个,如果RIG是可以k可着色的,则可以使用不多于k个寄存器完成寄存器分配。

例如,上述RIG是4可着色的,则可以使用4个寄存器完成寄存器分配。

图着色算法

图着色问题是一个NP-hard问题,但我们可以采用启发式的思想。假设图G有个节点m,它的邻节点个数少于m,令G‘G-{m},即G去掉节点m和相应的边形成G'。若G'能够k可着色的,那么G也可以。因为将m添加到已经着色的G'时,m的邻节点至多使用了k-1种颜色,那么总能找到一种颜色为m节点着色。因而可以使用这样的一种简化方法:

  • 选择一个邻节点个数小于k的节点t
  • 将节点t放入栈中,并从RIG中删除
  • 重复上述过程直到图中只剩下一个节点

然后给栈上的节点着色:

  • 从栈顶节点开始着色
  • 每次选择一个不同于已经着色的邻节点的颜色进行着色

例如上述的RIG,k=4,着色过程如下:

1)初始状态:

2)去除节点a

3)去除节点d

4)去除节点c

5)去除节点b

6)去除节点e:

7)去除节点f

8)给栈顶节点f着色:

9)给e着色,选择不同于f的颜色:

10)给b着色,选择不同于ef的颜色:

11)给c着色,选择不同于efb的颜色:

12)给d着色,选择不同于efc的颜色,可以选择和b相同的颜色:

13)给a着色,选择不同于fc的颜色,可以选择和e相同的颜色:
在这里插入图片描述

这就完成了RIG的着色,也即寄存器分配。但是,对于上述RIG,如果只有3个物理寄存器,再移除a后,则无法进行下去:
在这里插入图片描述
也就是说启发式的着色方法失败了。此时需要采用寄存器溢出的方法对上述方法进行修正。

溢出

寄存器溢出即在栈上申请一块内存来存放临时变量。例如,将f暂时存放在栈fa上,使用时候再从栈上读取。将f溢出到栈上后代码如下:

这里其实使用不同的名字 f1f2f3替代f更优,因为这可以减少RIG的边的数量,也即较少f活跃的区间:

此时,重新进行活跃分析,结果如下:

可以得到新的RIG图,并重新使用启发式的图着色方法即可完成寄存器分配,结果如下:
在这里插入图片描述

这里如何选择溢出的变量,有一些启发式的方法:

  • 选择有最多冲突的变量
  • 选择定值和使用比较少的变量
  • 避免溢出循环体内的变量

此外,寄存器分配还可以得到一个额外的优化收获,那就是给move指令的源和目的分配相同的物理寄存器,则可以删除该move指令。

本文介绍了比较经典的图着色的寄存器分配算法,此外目前使用比较广的还有线性扫描算法、整数线性规划算法等。LLVM中支持的寄存器分配算法有4种:Basic Register Allocator、Fast Register Allocator、PBQP Register Allocator、Greedy Register Allocator。大家可以去翻阅LLVM代码了解算法细节。

参考

  • https://tai-e.pascal-lab.net/lectures.html
  • https://web.stanford.edu/class/cs143/lectures/lecture16.pdf
  • 现代编译原理 C语言描述(修订版)

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

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

相关文章

centos7安装mysql数据库详细教程及常见问题解决

mysql数据库详细安装步骤 1.在root身份下输入执行命令: yum -y update 2.检查是否已经安装MySQL,输入以下命令并执行: mysql -v 如出现-bash: mysql: command not found 则说明没有安装mysql 也可以输入rpm -qa | grep -i mysql 查看是否已…

mac下安装vue cli脚手架并搭建一个简易项目

目录 1、确定本电脑下node和npm版本是否为项目所需版本。 2、下载vue脚手架 3、创建项目 1、下载node。 如果有node,打开终端,输入node -v和npm -v , 确保node和npm的版本,(这里可以根据自己的需求去选择,如果对最新版本的内容有…

python 源码中 PyId_stdout 如何定义的

python 源代码中遇到一个变量名 PyId_stdout,搜不到在哪里定义的,如下只能搜到引用的位置(python3.8.10): 找了半天发现是用宏来构造的声明语句: // filepath: Include/cpython/object.h typedef struct …

Gradle build 失败后提示.lock文件,解决办法

在Gradle build失败之后时,有时候强制关闭AndroidStudio,再次打开build时,会提示各种.lock 文件问题,删除了一个还有下一个,而且路径不一样。 一般情况下是这两个文件夹下的lockfile影响继续build %GRADLE_HOME%/ca…

目标检测任务中常用的数据集格式(voc、coco、yolo)

一、Pascal VOC VOC数据集(Annotation的格式是xmI) Pascal VOC数据集是目标检测的常用的大规模数据集之一,从05年到12年都会举办比赛,比赛任务task: 分类Classification目标检测Object Detection语义分割Class Segmentation实例分割Object…

基于java+swing+mysql图书管理系统v8.0

基于javaswingmysql图书管理系统v8.0 一、系统介绍二、功能展示1.登陆及主页2.图书类别添加3.图书类别维护4.图书添加5.图书维护 三、系统实现1.BookManageMainFrame.java 四、其它1.其他系统实现 五、获取源码 一、系统介绍 该系统实现了用户登陆、图书类别管理(图书类别添加…

yolov5 onnx模型 转为 rknn模型

1、转换为rknn模型环境搭建 onnx模型需要转换为rknn模型才能在rv1126开发板上运行,所以需要先搭建转换环境 模型转换工具 模型转换相关文件下载: 网盘下载链接:百度网盘 请输入提取码 提取码:teuc 将其移动到虚拟机中&#xf…

基本排序算法

目录 一,插入排序 二,希尔排序 三,选择排序 四,冒泡排序 五,快排 5.1 Hoare法 5.2 挖坑法 5.3 指针法 5.4 非递归写法 六,归并排序 6.1 递归 6.2 非递归 一,插入排序 基本思想&…

CorelDraw怎么做立体字效果?CorelDraw制作漂亮的3d立体字教程

1、打开软件CorelDRAW 2019,用文本工具写上我们所需要的大标题。建议字体选用比较粗的适合做标题的字体。 2、给字填充颜色,此时填充的颜色就是以后立体字正面的颜色。我填充了红色,并加上了灰色的描边。 3、选中文本,单击界面左侧…

superset为何无法上传excel,csv等外部文件

superset为何无法上传excel,csv等外部文件 这是由于没有打开数据库的上传外部文件的权限 1.打开数据库连接设置,选择Allow file uploads to database 2.发现这里的上传链接都可以使用

c++ 类

类的引入 c 语言的结构体只能定义变量 但是 c的结构体除了定义变量之外,还可以定义函数。 感受感受: #define _CRT_SECURE_NO_WARNINGS 1//我们声明一个结构体 struct Stack {// c可以把函数写在结构体中//叫成员函数:// 如下://c的写法&am…

股票回购不积极,遭分析师看空,汽车之家财务前景黯淡

来源:猛兽财经 作者:猛兽财经 第一季度财报后股价表现不佳 汽车之家(ATHM)于2023年5月11日公布了2023年第一季度业财报绩。 猛兽财经通过查询财报得知,汽车之家第一季度的实际营收为2.21亿美元,正常每股收…

uniapp实现预约时间选择弹窗组件

做了个组件&#xff0c;实现出当日预约时间组件&#xff0c;效果图如下 废话不多说&#xff0c;直接上代码&#xff0c;代码简单&#xff0c;参数自己任意改 <template><view class"inventory"><u-popup :show"show" :round"10"…

开源快速开发平台:做好数据管理,实现流程化办公!

做好数据管理&#xff0c;可以提升企业的办公协作效率&#xff0c;实现数字化转型。开源快速开发平台是深受企业喜爱的低代码开发平台&#xff0c;拥有多项典型功能&#xff0c;是可以打造自主可控快速开发平台&#xff0c;实现一对一框架定制的软件平台。在快节奏的社会中&…

Docker的安装与部署

Docker 基本概念介绍 通俗理解&#xff1a;镜像是类&#xff0c;容器是对象实例 仓库 应用商店、镜像 下载的应用安装程序、容器 应用程序 镜像(Image) 这里面保存了应用和需要的依赖环境 为什么需要多个镜像&#xff1f;当开发、构建和运行容器化应用程序时&#xff0c;我们…

redis集群设置

先下载redis数据库可以在一台机器上设置redis集群高可用 cd /etc/redis/ mkdir -p redis-cluster/redis600{1..6} for i in {1..6} do cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-s…

二叉搜索树的本质

引言 打算写写树形数据结构&#xff1a;二叉查找树、红黑树、跳表和 B 树。这些数据结构都是为了解决同一个基本问题&#xff1a;如何快速地对一个大集合执行增删改查。 本篇是第一篇&#xff0c;讲讲搜索树的基础&#xff1a;二叉搜索树。 基本问题 如何在一千万个手机号中…

UniSSOView 任意命令执行复现

免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使…

动态内存管理面试题

动态内存管理面试题 文章目录 动态内存管理面试题一、第一题此代码存在的问题运行结果分析原因修改 二、第二题此代码存在的问题运行结果分析原因修改 一、第一题 代码如下&#xff08;示例&#xff09;&#xff1a; #include<stdio.h> #include<string.h> #incl…

Android开发之Fragment动态添加与管理

文章目录 主界面布局资源两个工具Fragment主程序 主界面布局资源 在activity_main.xml中&#xff0c;声明两个按钮备用&#xff0c;再加入一个帧布局&#xff0c;待会儿用来展示Fragment。 <?xml version"1.0" encoding"utf-8"?> <LinearLayo…