寄存器分配:图着色算法

news2024/11/15 19:49:24

寄存器分配:图着色算法

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

背景

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

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语言描述(修订版)

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

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

相关文章

初步了解C++模板

一、函数模板 如果我们要写一个交换两个变量值的函数Swap&#xff0c;那么我们得对每一种类型都写一个&#xff0c;以便适用不同类型的参数&#xff0c;但是有了模板之后&#xff0c;可以简化操作 template<class T> void Swap(T& x, T& y) {T tmp x;x y;y …

百题千解计划【CSDN每日一练】订班服(附解析+多种实现方法:Python、Java、C、C++、C#、Go、JavaScript)

如果决意去做一件事了,就不要再问自己和别人值不值得,心甘情愿才能理所当然,理所当然才会义无反顾。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌟[2] 2022年度博客之星人工智能领域TOP4🌟 🏅[3] 阿里云社区特邀专…

大数据处理框架-Spark DataFrame构造、join和null空值填充

1、Spark DataFrame介绍 DataFrame是Spark SQL中的一个概念&#xff0c;它是一个分布式的数据集合&#xff0c;可以看作是一张表。DataFrame与RDD的主要区别在于&#xff0c;前者带有schema元信息&#xff0c;即DataFrame所表示的二维表数据集的每一列都带有名称和类型。 2、构…

Statefulset部署应用

上一部分我们分享到了使用 RS 没有办法让自己管理的多个 pod 都有一个独立的持久化声明&#xff0c;RS 没有办法在指定模板中对不同的 pod 做差异化处理 使用多个 RS 来分别管理自己的的一个 pod&#xff0c;当我们扩缩容的时候&#xff0c;也会出现问题&#xff0c;老的 pod …

10. Mybatis 项目的创建

目录 1. Mybatis 概念 2. 第一个 Mybits 查询 2.1 创建数据库和表 2.2 添加 Mybatis 框架支持 2.3 添加配置文件 2.4 配置 MyBatis 中的 XML 路径 2.5 添加业务代码 在学习 Mybatis 之前&#xff0c;我们需要知道 Mybatis 和 Spring 没有任何的关系。如果一定要强调二者…

UniSSOView 任意命令执行复现

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

什么是专业级OV通配符https证书

通配符SSL证书指的是SSL数字证书中可以用一张SSL数字证书保护主域名以及主域名下所有子域名的数字证书。我们按照验证方式将通配符SSL数字证书分为DV基础型和OV企业型通配符SSL证书两种&#xff0c;专业级的OV通配符SSL证书指的是需要验证域名所有权以及申请主体真实性的OV企业…

NI-DAQ Win10+QT+Cmake 开发环境搭建

文章目录 一.安装DAQ采集卡驱动二.NI MAX软件的使用三. QT利用Cmake构建工具搭建NI DAQ开发环境 一.安装DAQ采集卡驱动 到NI官网&#xff0c;选择技术支持&#xff0c;软件下载 搜索DAQ-mx NI测量设备均附带NI-DAQmx驱动软件。NI-DAQmx驱动软件是一个用途广泛的库&#xff0c;…

win10误删u盘文件怎么恢复数据?用5步解决数据丢失问题

求助&#xff0c;求助&#xff0c;Windows10电脑把U盘里面的文件误删了&#xff0c;其中一个txt文档对我比较重要&#xff0c;请问如何恢復? ——Win10误删U盘文件怎么恢复数据&#xff1f;在使用Windows 10操作系统时&#xff0c;有时候我们可能会不小心删除了U盘中的重要文件…

认可功能介绍 - 技术声誉靠认可

需求 大家在学习和工作中&#xff0c; 经常碰到一些热心帮助自己的人&#xff0c; 我们怎么向他们表示感谢呢&#xff1f; 各位博主在 CSDN 也做了很多贡献&#xff0c;也有不少用户在做各种各样的社区活动&#xff0c;这些活动给我们的领军人物什么回馈呢&#xff1f; 这些…

UG\NX二次开发 使用UF_MODL_create_symb_thread创建”螺纹符号“例子

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 使用UF_MODL_create_symb_thread创建”螺纹符号“例子 效果: 代码: #include <stdio.h> #include <string.h> #include <uf.h> #include <uf_modl.h> #include <…

aardio - 关于 loadcode 和 loadcodex 的用法

关于 loadcode 和 loadcodex 的用法&#xff0c;资料较少&#xff0c;我简单写了几种用法&#xff0c;作为抛砖引玉。 大家还有其他使用技巧&#xff0c;请跟帖&#xff1a; import consoletest1 /** myTestFunc1 function(){ return myFunc1; } **/ loadcodex(test1); co…

贝莱德研究论文:资产配置中的比特币比例,85% or 3%?

* * * 原创&#xff1a;刘教链 * * * 号外&#xff1a;今天在「刘教链内参」发表了《内参&#xff1a;从华尔街解读美联储加息看我们战胜华尔街的底层逻辑》&#xff0c;欢迎关注公众号「刘教链内参」并阅读。 --- 隔夜比特币继续在29k上方震荡。并未延续缓慢修复走势&#xf…

企业服务器中了360后缀勒索病毒,勒索病毒解密数据恢复数据库修复

近年来&#xff0c;随着网络技术的不断发展&#xff0c;也导致互联网威胁不断升级&#xff0c;各种类型的勒索病毒不断出现&#xff0c;给企业信息安全带来了巨大威胁。360后缀勒索病毒是其中一种&#xff0c;它能够加密企业的关键数据&#xff0c;并以赎金形式要求解密。近期&…

瑞芯微|rk3568 uart快速上手

一、调试环境 平台&#xff1a;rk3568 kernel: 4.19.232 SDK: rk_android11.0_sdk Board: rk3568-evb1-ddr4-v10 二、 rk3568 uart控制器 1. 特性&#xff1a; rk3568 UART控制器特性如下&#xff1a; - UART控制器通道&#xff1a;UART0~UART8 【datasheet好像写的有问…

44.C++ static的用法

目录 一、静态成员变量 二、静态成员函数 三、局部静态变量 今天进行了新的学习。C关于static的用法。 只有.cpp文件能够被编译链接 在C中&#xff0c;static关键字有多种用法&#xff0c;主要用于以下几个方面&#xff1a; 一、静态成员变量 在类中使用static关键字修…

使用easyui的tree组件实现给角色快捷分配权限功能

这篇文章主要介绍怎么实现角色权限的快捷分配功能&#xff0c;不需要像大多数项目的授权一样&#xff0c;使用类似穿梭框的组件来授权。 具体实现&#xff1a;通过菜单树的勾选和取消勾选来给角色分配权限&#xff0c;在这之前&#xff0c;需要得到角色的菜单树&#xff0c;角色…

基于内核链表和JSON的MQTT的使用

一、内核链表 1.回顾单链表的插入和遍历 假设学生结构体信息如下&#xff0c;封装一个单链表的插入接口和遍历输出的接口&#xff0c;在主函数中利用封装的接口生成一个学生链表&#xff0c;并遍历输出链表的学生信息。 #include <stdio.h> #include <string.h>…

Spring MVC学习笔记,包含mvc架构使用,过滤器、拦截器、执行流程等等

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. 文章目录 Spring MVC 习笔记1、Spring MVC demo2、Spring MVC 中常见注解3、数据处理3.1、请求参数处理3.2、响应数据处理 4、RESTFul 风格5、静态资源处理6、HttpMessageConverter 转换器7、过…

iOS开发-下拉刷新动画依次渐隐渐显Indicator指示器效果

iOS开发-下拉刷新动画依次渐隐渐显Indicator指示器效果 之前开发中实现下拉刷新动画三个球依次渐隐渐显指示器效果。 一、效果图 二、基础动画 CABasicAnimation类的使用方式就是基本的关键帧动画。 所谓关键帧动画&#xff0c;就是将Layer的属性作为KeyPath来注册&#xf…