llvm中如何利用分支概率和基本块频率估计
1. 背景
llvm自2.9版以后,已经集成了对分支概率和基本块频率的静态分析。
分支概率(branch probability)是指在程序的控制流图中,从控制流从一个基本块A到其任意后继基本块Si的概率。控制流从基本块A到其所有后继基本块的概率之和为1. 基本块频率(block frequency)是指在程序的控制流图中,任意基本块的执行次数。这两种信息都可以通过静态分析得到。其原理如下【1】【2】:
An alternative is static profiling, in which a compiler estimates execution frequencies (not absolute counts) with static program analysis. A static profile eliminates the drawbacks of dynamic profiling— if it accurately captures a program’s dynamic behavior. Recent work suggests that static analysis can predict dynamic program behavior. Fisher and Freudenberger [Fisher-92] observed that many programs’ dynamic branching behavior is independent of their input data. Ball and Larus developed a simple algorithm that statically predicts the outcome of a conditional branch with good accuracy [Ball-93]. Wagner et al. usedl simple estimates of branch probabilities to compute static profiles [Wagner-94]. (见文献【2】)
2. llvm3.3中的相关文件
Support/BranchProbability.cpp(.h): 实现一个用来表示分支概率的数据结构
Analysis/BranchProbabilityInfo.cpp(.h): 实现一个在basic block级别进行分支概率估计的FunctionPass
CodeGen/MachineBranchProbabilityInfo.cpp(.h): 实现一个在machine basic block级别进行分支概率估计的ImmutablePass
Support/BlockFrequency.cpp(.h): 实现一个用来表示基本块频率的数据结构
Analysis/BlockFrequencyInfo.cpp(.h): 实现一个在basic block级别进行基本块频率估计的FunctionPass
CodeGen/MachineBlockFrequency.cpp(.h): 实现一个在machine basic block级别进行基本块频率估计的MachineFunctionPass
Analysis/BlockFrequencyImpl.h: 在basic block级别和machine basic block级别共用的基本块频率估计的实现
3. llvm3.3中的相关实现
3.1 分支概率分析
3.1.1 在basic block级别,分支概率分析的实现主要参考文献【2】的方法,利用几个基本启发式来给分支加权。
for (po_iterator<BasicBlock *> I = po_begin(&F.getEntryBlock()), E = po_end(&F.getEntryBlock()); I != E; ++I) {
DEBUG(dbgs() << "Computing probabilities for " << I->getName() << "\n");
if (calcUnreachableHeuristics(*I))
continue;
if (calcMetadataWeights(*I))
continue;
if (calcColdCallHeuristics(*I))
continue;
if (calcLoopBranchHeuristics(*I))
continue;
if (calcPointerHeuristics(*I))
continue;
if (calcZeroHeuristics(*I))
continue;
if (calcFloatingPointHeuristics(*I))
continue;
calcInvokeHeuristics(*I);
}
return false;
}
3.1.2 在machine basic block级别,分支概率的实现实际上依赖于basic block级别的分支概率分析结果,所以MachineBranchProbabilityInfo并不是一个独立的MachineFunctionPass.
3.2 基本块频率分析
3.2.1 在basic block级别和machine basic block级别共用基本块频率估计的实现
bool BlockFrequencyInfo::runOnFunction(Function &F) {
BranchProbabilityInfo &BPI = getAnalysis<BranchProbabilityInfo>();
BFI->doFunction(&F, &BPI);
return false;
}
bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
MachineBranchProbabilityInfo &MBPI = getAnalysis<MachineBranchProbabilityInfo>();
MBFI->doFunction(&F, &MBPI);
return false;
}
3.2.2 上面的代码还可以看出,基本块频率分析依赖于分支概率分析。因此,如果要利用这两种分析结果,只需要在自己的FunctionPass或者MachineFunctionPass里面进行类似如下的修改(建议参考CodeGen/MachineBlockPlacement.cpp):
1)修改getAnalysisUsage函数如下:
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineBranchProbabilityInfo>();
AU.addRequired<MachineBlockFrequencyInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
2)修改runOnMachineFunction函数如下
bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) {
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
...
//打印分支概率信息
std::string szInfo;
raw_fd_ostream S("machinBranchProbs.txt", szInfo, raw_fd_ostream::F_Append);
for (MachineFunction::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
MachineBasicBlock *MBB = BI;
for (MachineBasicBlock::const_succ_iterator SI =MBB->succ_begin(), EI = MBB->succ_end(); SI != EI; ++SI) {
MachineBasicBlock *mBlock = *SI;
MBPI->printEdgeProbability(S << " ", MBB, mBlock);
}
}
S.close();
//打印基本块频率信息
raw_fd_ostream S1("machinBlockFreq.txt", szInfo, raw_fd_ostream::F_Append);
if (MBFI) MBFI->print(S1);;
S1.close();
...
return false;
}
4. 参考文献:
llvm中如何利用分支概率和基本块频率估计的更多相关文章
- Git 分支-利用分支进行开发的工作流程
3.4 Git 分支 - 利用分支进行开发的工作流程 利用分支进行开发的工作流程 现在我们已经学会了新建分支和合并分支,可以(或应该)用它来做点什么呢?在本节,我们会介绍一些利用分支进行开发的工作流程 ...
- javascript基础入门之js中的结构分支与循环语句
javascript基础入门之js中的结构分支与循环语句 程序的结构①顺序结构:自上而下:②选择(分支)结构:多条路径,根据不同的条件,只执行其中一个:③循环结构:重复某些代码④配合特定的语句实现选择 ...
- git 操作 :从远程仓库gitLab上拉取指定分支到本地仓库;git如何利用分支进行多人开发 ;多人合作代码提交实践
例如:将gitLab 上的dev分支拉取到本地 git checkout -b dev origin/dev 在本地创建分支dev并切换到该分支 git pull origin dev 就可以把git ...
- Git中如何利用生成SSH个人公钥访问git仓库
Git中如何利用生成SSH个人公钥访问git仓库方法(这里以coding平台为例): 1. 获取 SSH 协议地址 在项目的代码页面点击 SSH 切换到 SSH 协议, 获得访问地址, 请使用这个地址 ...
- 开发与测试整体过程中的Git分支merge流程
开发与测试整体过程中的Git分支merge流程 Git分支merge之开发流程 首先在Gitlab上有个仓库存储着原始的项目代码,其中包含一个叫master的分支.然后可能按功能进行分配,由不同的开发 ...
- C/S模式开发中如何利用WebBrowser控件制作导航窗体
原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见 ...
- CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用
https://securelist.com/cve-2019-0797-zero-day-vulnerability/89885/ 前言 在2019年2月,卡巴实验室的自动漏洞防护(AEP)系统检测 ...
- Vuejs(14)——在v-for中,利用index来对第一项添加class
版权声明:出处http://blog.csdn.net/qq20004604 (1)在v-for中,利用index来对第一项添加class <a class="list-group-i ...
- Flex中如何利用FocusManager类的setFocus函数设置TextInput的焦点的例子
参考:https://blog.csdn.net/liruizhuang/article/details/5876455 <?xml version="1.0" encodi ...
随机推荐
- CentOS7中开机出现end_request:I/O error,dev fd0,sector 0的解决办法
https://blog.csdn.net/wangjinyang_123/article/details/40583635
- matplotlib 练习
官网 vamei的博客还是读了就秒懂,很妙, matplotlib核心剖析 官网翻译也不错,但缺少了 Logarithmic and other nonlinear axis对数等非线性轴 这一模块 ...
- Java Hibernate和.Net EntityFramework 如何在提交事务之前 就拿到需要新增实体的Id
在Hibernate中很容易做到这一点,因为hibernate在事务commit之前 还有一个save方法,这个save方法就可以持久化并且拿到Id. 但是EF并不可以呀,EF是将对象标记为新增状态 ...
- Gitlab基本管理(二)
一. Gitlab分支 1. 切换到项目位置. 2. 创建一个项目的一新分支. mike@win10-001 MINGW64 ~/cookbook/cookbook (master) $ git br ...
- ThinkPHP 多语言的实现
1.按照官方文档进行修改 2.注意区分项目语言包和系统语言包 3.实现语言包和数据库语言同步切换 4.thinkPHP多语言实现与Cookie有关, 谷歌浏览器下按F12查看Request Heade ...
- Mysql Federated Server 示例
Federated存储引擎访问在远程数据库的表中的数据,而不是本地的表.创建一个Federated表的时候,服务器在数据库目录创建一个表定义文件.无其它表被创建,因为实际的数据在一个远程数据库上.这不 ...
- Java实现web在线预览office文档与pdf文档实例
https://yq.aliyun.com/ziliao/1768?spm=5176.8246799.blogcont.24.1PxYoX 摘要: 本文讲的是Java实现web在线预览office文档 ...
- C#字符串(Sring)操作
//字符串访问 //string s = "ABCD"; //Console.WriteLine(s[0]);//第0位字符 ...
- 湖南大学ACM程序设计新生杯大赛(同步赛)L - Liao Han
题目描述 Small koala special love LiaoHan (of course is very handsome boys), one day she saw N (N<1e1 ...
- 最短路——spfa
适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一 ...