当前位置: 首页 > news >正文

MachineSink - 优化阅读笔记

注:该优化与全局子表达式消除刚好是相反的过程,具体该不该做这个优化得看代价模型算出来的结果(有采样文件指导算得会更准确)

该优化过程将指令移动到后继基本块中,以便它们不会在不需要其结果的路径上执行。

该优化过程并非旨在替代或完全替代 LLVM IR 级别的下沉优化。它仅设计用于下沉简单的结构,这些结构在 lowering 和指令选择之前不会显现.

测试用例:

grep "machine-sink" llvm/test/* -Rnw|grep X86|grep -v debug
./build4/bin/llvm-lit llvm/test/DebugInfo/MIR/X86/machinesink.mir -a
./build4/bin/llc -run-pass=dot-machine-cfg llvm/test/DebugInfo/MIR/X86/machinesink.mir
dot .Process.dot -T svg -o Process.dot.svg
dot .test2.dot -T svg -o test2.dot.svg
dot .test3.dot -T svg -o test3.dot.svg./build4/bin/llc -mtriple=x86_64-unknown-unknown -run-pass=machine-sink -o - ./llvm/test/DebugInfo/MIR/X86/machinesink.mir &> dd
./build4/bin/llc -mtriple=x86_64-unknown-unknown -run-pass=removeredundantdebugvalues -o - ./llvm/test/DebugInfo/MIR/X86/machinesink.mir &> ddd

效果:
在这里插入图片描述在这里插入图片描述

几个重要的接口:

bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {// 更新寄存器信息RegClassInfo.runOnMachineFunction(MF);// 遍历每个 BB, 寻找优化的场景for (auto &MBB: MF)MadeChange |= ProcessBlock(MBB);// 处理需要打破的临界边auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, *this);
void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) {// 1. 检查 CSR 数组的每个元素是否与之前分析的相同const MCPhysReg *CSR = MRI.getCalleeSavedRegs();// 2. 如果有改变,记录每一个 CSR 及它的别名for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI)CalleeSavedAliases[*AI] = *I;// 3. 更新每个 CSRs 的分配优先级if (IgnoreCSRForAllocOrder.size() != CSRHintsForAllocOrder.size() ||IgnoreCSRForAllocOrder != CSRHintsForAllocOrder) {// 4. 获取寄存器的成本RegCosts = TRI->getRegisterCosts(*MF);// 5. 更新保留寄存器const BitVector &RR = MF->getRegInfo().getReservedRegs();// 6. 更新寄存器压力unsigned NumPSets = TRI->getNumRegPressureSets();// build4/lib/Target/X86/X86GenRegisterInfo.inc:11902// build4/lib/Target/AArch64/AArch64GenRegisterInfo.inc:103840
}
bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {// 待优化BB需要有多个后继,且不是死的基本块// 逆序遍历每条指令do {// 记录指令的 debug 信息// 执行琐碎的前向聚合, SRC=DRC的拷贝指令的替换bool Joined = PerformTrivialForwardCoalescing(MI, &MBB);// 尝试下沉指令if (SinkInstruction(MI, SawStore, AllSuccessors))} while (!ProcessedBegin);
}
bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,AllSuccsCache &AllSuccessors) {TII->shouldSink(MI); // X86 always trueMI.isSafeToMove(AA, SawStore); // MachineInstr.cpp:1259 !store !call !load !phi !inlineasm !positino ...MachineBasicBlock *SuccToSinkTo =FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge, AllSuccessors);// 不要破坏隐式空指针检查。这是一种性能启发,而非正确性所必需// 如果 MI 可能被隐式空指针检查优化用作内存操作,则返回 trueSinkingPreventsImplicitNullCheck(...);// llvm/test/CodeGen/X86/implicit-null-check.ll// br i1 %c, label %is_null, label %not_null, !make.implicit !0// 这应该包括支持在当前块内下沉指令,以缩短其寄存器活跃范围。我们经常将指令下沉到大块的顶部,但最好在它们在块中第一次使用之前也将其下沉。但是,此变换必须小心,不要增加寄存器压力,例如,如果下沉 "x = y + z",但它杀死了 y 和 z,那么会增加 y 和 z 的寄存器活跃范围,而只会减小 x 的寄存器活跃范围MachineBasicBlock *SuccToSinkTo = FindSuccToSinkTo(MI, ParentBlock, BreakPHIEdge, AllSuccessors);// 检查是否会引入僵尸寄存器if (SuccToSinkTo->isLiveIn(Reg))// 如果需要打破危险边界, // 或 会破坏 PHI 边界if (SuccToSinkTo->pred_size() > 1) if (blockPrologueInterferes(SuccToSinkTo, InsertPos, MI, TRI, TII, MRI)) || if (BreakPHIEdge)// 延后打破危险边界,就记录一下bool Status = PostponeSplitCriticalEdge(MI, ParentBlock, SuccToSinkTo, BreakPHIEdge);// ToSplit.insert(std::make_pair(FromBB, ToBB));// 查找插入点, 跳过 phi和序幕指令SuccToSinkTo->SkipPHIsAndLabels(SuccToSinkTo->begin());// 收集需要一并下沉的debug指令DbgUsersToSink.push_back({DbgMI, SmallVector<unsigned, 2>(1, MO.getReg())});// 下沉指令及其相关调试指令performSink(MI, *SuccToSinkTo, InsertPos, DbgUsersToSink);// 移动指令:SuccToSinkTo.splice(InsertPos, ParentBlock, MI, ++MachineBasicBlock::iterator(MI));// 处理debug信息:attemptDebugCopyProp(MI, *DbgMI, Reg)// 清除 kill 标记RegsToClearKillFlags.insert(MO.getReg());
}
MachineBasicBlock *
MachineSinking::FindSuccToSinkTo(MachineInstr &MI, MachineBasicBlock *MBB,bool &BreakPHIEdge,AllSuccsCache &AllSuccessors) {// 检查要下沉的指令的每个操作数for (const MachineOperand &MO : MI.operands()) {// 对于虚拟寄存器// 需要能安全移动if (!TII->isSafeToMoveRegClassDefs(MRI->getRegClass(Reg)))// llvm/lib/Target/X86/X86InstrInfo.cpp:7534// 否则,我们应该查看所有的后继块并决定应该下沉到哪一个。如果我们有可靠的块频率信息(frequency != 0),则将具有较小频率的后继块优先级更高,否则优先考虑较小的循环深度for (MachineBasicBlock *SuccBlock :GetAllSortedSuccessors(MI, MBB, AllSuccessors)) {// 除了MBB的直接后继, 被 MBB 作为直接支配者的 DomTree 子节点也会被遍历/// AllUsesDominatedByBlock - 如果指定寄存器的所有使用都在指定块支配的块中发生,则返回 true, 如果任何使用在定义块中,则返回 false,因为在使用之后移动定义是不合法的。if (AllUsesDominatedByBlock(Reg, SuccBlock, MBB,BreakPHIEdge, LocalUse)) {}// 检查收益if (!isProfitableToSinkTo(Reg, MI, MBB, SuccToSinkTo, AllSuccessors))}
}bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,MachineBasicBlock *MBB,MachineBasicBlock *SuccToSinkTo,AllSuccsCache &AllSuccessors) {// 1. 不 反向支配 Def BB!PDT->dominates(SuccToSinkTo, MBB)// 2. 循环嵌套更浅if (CI->getCycleDepth(MBB) > CI->getCycleDepth(SuccToSinkTo))// 3. 寄存器压力不超限if (isRegisterPressureSetExceedLimit(MRI->getRegClass(Reg)))
}

遗留问题:

  1. 与 llvm ir 中 sink 的区别
  2. split critical edge 具体是怎么做的

LLVM IR 中搜索到其他三个 Sink 相关的pass:

# find llvm/lib/ -name "*.cpp"|grep "sink" -i
llvm/lib/Transforms/Scalar/Sink.cpp
llvm/lib/Transforms/Scalar/LoopSink.cpp
llvm/lib/Transforms/Scalar/GVNSink.cpp
llvm/lib/CodeGen/MachineSink.cpp

相关文章:

MachineSink - 优化阅读笔记

注&#xff1a;该优化与全局子表达式消除刚好是相反的过程&#xff0c;具体该不该做这个优化得看代价模型算出来的结果(有采样文件指导算得会更准确) 该优化过程将指令移动到后继基本块中&#xff0c;以便它们不会在不需要其结果的路径上执行。 该优化过程并非旨在替代或完全…...

虾皮shopee根据ID取商品详情 API

公共参数 名称类型必须描述keyString是免费申请调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认y…...

你知道数据库有哪些约束吗?

目录 1. NULL约束 2. 唯一&#xff08;UNIQUE&#xff09;约束 3. 默认值&#xff08;DEFAULT&#xff09;约束 4. 主键约束 5. 外键约束 6. CHECK约束 数据库约束是一种用于确保数据库中数据完整性和一致性的规则或条件。这些约束可以应用于表、列或整个数据库&#xff0…...

QT----基于QT的人脸考勤系统(未完成)

目录 1 编译opencv库1.1 下载源代码1.2 qt编译opencv1.3 执行Cmake一直卡着data: Download: face_landmark_model.dat 2 编译SeetaFace2代码2.1 遇到报错By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has2.2遇到报错Model missing 3 测试…...

机试:成绩排名

问题描述: 代码示例: #include <bits/stdc.h> using namespace std;int main(){cout << "样例输入" << endl; int n;int m;cin >> n;int nums[n];for(int i 0; i < n; i){cin >> nums[i];}// 排序for(int i 0; i < n; i){//…...

C编程基础四十分笔记

都是一些基础的C语言 一 输入一个整数&#xff0c;计算这个整数有几位二 编写程序计算一个分布函数三 输入一个字符串&#xff0c;再随便输入一个字母&#xff0c;判断这个字母出现几次四 求 1到10的阶乘之和五 求一个球体体积六 写一个链表&#xff0c;存1&#xff0c;2&#…...

k8s关于pod

目录 1、POD 的创建流程 kubectl 发起创建 Pod 请求&#xff1a; API Server 接收请求并处理&#xff1a; 写入 Etcd 数据库&#xff1a; Kubelet 监听并创建 Pod&#xff1a; Pod 状态更新和汇报&#xff1a; 2、POD 的状态解析 1. Pending Pod 2. Running Pod 3. S…...

yum安装mysql 数据库tab自动补全

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…...

MBT-Net

feature F&#xff0c;edge feature E-F where r related to the relative position 辅助信息 作者未提供代码...

大数据赋能,能源企业的智慧转型之路

在数字洪流中&#xff0c;大数据已经成为推动产业升级的新引擎。特别是在能源行业&#xff0c;大数据的应用正引领着一场深刻的智慧转型。今天&#xff0c;我们就来探讨大数据如何在能源企业中发挥其独特的魅力&#xff0c;助力企业提效降本&#xff0c;实现绿色发展。 动态监控…...

2024考研国家线公布,各科分数线有哪些变化?考研国家线哪些涨了,哪些跌了?可视化分析告诉你

结论在文章结尾 2024考研国家线 一、近五年国家线趋势图-学术硕士 文学 管理学 工学照顾专业 体育学 交叉学科 军事学 历史学 理学 享受少数名族照顾政策的考生 中医类照顾专业 教育类 艺术类 医学 工学 哲学 法学 农学 经济学 二、近五年国家线趋势图-专业硕士 中医 应用心理 …...

高效、安全的APP分发与推广平台

在信息化快速发展的今天&#xff0c;APP已经成为人们生活中不可或缺的一部分。然而&#xff0c;对于众多APP开发者来说&#xff0c;如何让自己的APP在众多竞争者中脱颖而出&#xff0c;被更多用户所认知和下载&#xff0c;成为了一个亟待解决的问题。这时&#xff0c;一个高效、…...

浅谈异或运算

异或&#xff0c;是一个数学运算符&#xff0c;英文为exclusive OR&#xff0c;缩写为xor&#xff0c;应用于逻辑运算。异或的数学符号为“⊕”&#xff0c;计算机符号为“xor”。其运算法则为&#xff1a; a⊕b &#xff08;a ∧ b&#xff09; ∨ &#xff08;a ∧b&#xf…...

Linux下platform总线

一. 简介 前面我们讲了设备驱动的分离&#xff0c;并且引出了总线 (bus) 、驱动 (driver) 和设备 (device) 模型&#xff0c;比如 I2C 、 SPI 、 USB 等总线。 但是&#xff0c;在 SOC 中有些外设是没有总线这个概念的&#xff0c;但是又要使用总 线、驱动和设备模型该怎么…...

C# EPPlus导出dataset----Excel2绘制图像

一、生成折线图方法 /// <summary> ///生成折线图 /// </summary> /// <param name="worksheet">sheet页数据 </param> /// <param name="colcount">总列数</param> /// &l…...

2024年云服务器ECS价格表出炉——阿里云

2024年阿里云服务器租用费用&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核4G服务…...

Grafana

介绍 官网&#xff1a;https://grafana.com/ Grafana 是一个开源的指标分析和可视化工具&#xff0c;它被广泛用于展示和监控云基础设施和应用程序的实时数据。Grafana 提供了一个强大且易于使用的界面&#xff0c;允许用户创建各种图表、图形和仪表盘&#xff0c;以直观地展…...

InnoDB记录结构

InnoDB页简介 InnoDB是一个将表中的数据存储到磁盘上的存储引擎&#xff0c;所以即使关机后重启我们的数据还是存在的。而真正处理数据的过程是发生在内存中的&#xff0c;所以需要把磁盘中的数据加载到内存中&#xff0c;如果是处理写入或修改请求的话&#xff0c;还需要把内…...

【框架学习 | 第六篇】SpringBoot基础篇(快速入门、自动配置原理分析、配置文件、整合第三方技术、拦截器、文件上传/下载、访问静态资源)

文章目录 1.SpringBoot简介1.1原有Spring优缺点分析1.1.1Spring优点1.1.2Spring缺点 1.2SpringBoot概述1.2.1SpringBoot解决上述Spring的缺点1.2.2SpringBoot特点1.2.3SpringBoot核心功能 2.SpringBoot快速入门2.1代码实现2.1.1创建Maven工程2.1.2添加SpringBoot的起步依赖2.1.…...

使用 ReclaiMe Pro 恢复任意文件系统(Win/Linux/MacOS)

天津鸿萌科贸发展有限公司是 ReclaiMe Pro 数据恢复软件授权代理商。 ReclaiMe Pro 是一个通用工具包&#xff0c;几乎可以用于从所有文件系统&#xff08;从 Windows 系列文件系统、Linux 和 MacOS&#xff09;中恢复数据。此外&#xff0c;考虑到数据恢复工作的具体情况&…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...