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 ...
随机推荐
- 写在Web考试后的一点小总结
在实验室折腾附加题折腾了一个多钟没做出来……晚上回到宿舍决定再试一试,按原来的思路居然行了,目测在实验室的时候什么地方打错字了吧(心在流血) 实现晃过元素后出现跟随鼠标的悬浮窗,只有几行代码给我折腾了 ...
- 用js 的for循环打印三角形,提取水仙花数,求本月多少天
第一题:用for循环打印三角形 //第一个 for(var x = 1;x <= 4;x++){ //控制行数 :由 1 到 4 for(var y = 1;y <= x;y++){ // ...
- ASP.NET MVC 获取计算机字体
//加载计算机上可用的字体 public string LoadFonts() { try { var fontCollection = new InstalledFontCollection(); ...
- Webpack, VSCode 和 Babel 组件模块导入别名
很多时候我们使用别人的库,都是通过 npm install,再简单的引入,就可以使用了. 1 2 import React from 'react' import { connect } fr ...
- Django实现单用户登录
最近由于要毕业了写论文做毕设,然后还在实习发现已经好久都没有写博客了.今天由于工作需求,需要用Django实现单用户登录.大概意思就是跟QQ一样的效果,每个账号只能一个地方登录使用,限制账号的登录次数 ...
- saltstack 开发
最近跟总部一个项目用saltstack封装api来用,可以很轻松的实现restful api发布,提供别人直接调用 salt 本身有2个内置变量(__salt__, __opts__),通过salt ...
- FastReport.Net使用:[14]文本控件使用
文本控件(Text)是FastReport中最常用的控件了,它可以是一行\多行文本.数据源的列.报表参数.汇总值.表达式,它还可以是以上任何元素的组合. 如何使用文本编辑器 1.双击文本框进入文本编辑 ...
- 【BZOJ 4169】 4169: Lmc的游戏 (树形DP)
4169: Lmc的游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 44 Solved: 25 Description RHL有一天看到lmc在 ...
- [SPOJ SEQN] [hdu3439]Sequence
题目就是求C(n,k)*H(n - k)%m 0<= k<= n <=10^9, 1 <= m <= 10^5, n != 0 其中H(n)是错排第n项. 对于C(n,k ...
- hdu 3089 (快速约瑟夫环)
Josephus again Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...