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. 参考文献:

【1】. Hashemi, A., Kaeli, D., Calder, B.: Procedure mapping using static call graph estimation. In: Workshop on Interaction between Compiler and Computer Architecture, San Antonio, TX (1997) 
【2】. Youfeng Wu, James R. Larus: Static branch frequency and program profile analysis. MICRO 1994: 1-11


llvm中如何利用分支概率和基本块频率估计的更多相关文章

  1. Git 分支-利用分支进行开发的工作流程

    3.4 Git 分支 - 利用分支进行开发的工作流程 利用分支进行开发的工作流程 现在我们已经学会了新建分支和合并分支,可以(或应该)用它来做点什么呢?在本节,我们会介绍一些利用分支进行开发的工作流程 ...

  2. javascript基础入门之js中的结构分支与循环语句

    javascript基础入门之js中的结构分支与循环语句 程序的结构①顺序结构:自上而下:②选择(分支)结构:多条路径,根据不同的条件,只执行其中一个:③循环结构:重复某些代码④配合特定的语句实现选择 ...

  3. git 操作 :从远程仓库gitLab上拉取指定分支到本地仓库;git如何利用分支进行多人开发 ;多人合作代码提交实践

    例如:将gitLab 上的dev分支拉取到本地 git checkout -b dev origin/dev 在本地创建分支dev并切换到该分支 git pull origin dev 就可以把git ...

  4. Git中如何利用生成SSH个人公钥访问git仓库

    Git中如何利用生成SSH个人公钥访问git仓库方法(这里以coding平台为例): 1. 获取 SSH 协议地址 在项目的代码页面点击 SSH 切换到 SSH 协议, 获得访问地址, 请使用这个地址 ...

  5. 开发与测试整体过程中的Git分支merge流程

    开发与测试整体过程中的Git分支merge流程 Git分支merge之开发流程 首先在Gitlab上有个仓库存储着原始的项目代码,其中包含一个叫master的分支.然后可能按功能进行分配,由不同的开发 ...

  6. C/S模式开发中如何利用WebBrowser控件制作导航窗体

    原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见 ...

  7. CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用

    https://securelist.com/cve-2019-0797-zero-day-vulnerability/89885/ 前言 在2019年2月,卡巴实验室的自动漏洞防护(AEP)系统检测 ...

  8. Vuejs(14)——在v-for中,利用index来对第一项添加class

    版权声明:出处http://blog.csdn.net/qq20004604 (1)在v-for中,利用index来对第一项添加class <a class="list-group-i ...

  9. Flex中如何利用FocusManager类的setFocus函数设置TextInput的焦点的例子

    参考:https://blog.csdn.net/liruizhuang/article/details/5876455 <?xml version="1.0" encodi ...

随机推荐

  1. CentOS7中开机出现end_request:I/O error,dev fd0,sector 0的解决办法

    https://blog.csdn.net/wangjinyang_123/article/details/40583635

  2. matplotlib 练习

    官网 vamei的博客还是读了就秒懂,很妙, matplotlib核心剖析 官网翻译也不错,但缺少了 Logarithmic and other nonlinear axis对数等非线性轴  这一模块 ...

  3. Java Hibernate和.Net EntityFramework 如何在提交事务之前 就拿到需要新增实体的Id

    在Hibernate中很容易做到这一点,因为hibernate在事务commit之前  还有一个save方法,这个save方法就可以持久化并且拿到Id. 但是EF并不可以呀,EF是将对象标记为新增状态 ...

  4. Gitlab基本管理(二)

    一. Gitlab分支 1. 切换到项目位置. 2. 创建一个项目的一新分支. mike@win10-001 MINGW64 ~/cookbook/cookbook (master) $ git br ...

  5. ThinkPHP 多语言的实现

    1.按照官方文档进行修改 2.注意区分项目语言包和系统语言包 3.实现语言包和数据库语言同步切换 4.thinkPHP多语言实现与Cookie有关, 谷歌浏览器下按F12查看Request Heade ...

  6. Mysql Federated Server 示例

    Federated存储引擎访问在远程数据库的表中的数据,而不是本地的表.创建一个Federated表的时候,服务器在数据库目录创建一个表定义文件.无其它表被创建,因为实际的数据在一个远程数据库上.这不 ...

  7. Java实现web在线预览office文档与pdf文档实例

    https://yq.aliyun.com/ziliao/1768?spm=5176.8246799.blogcont.24.1PxYoX 摘要: 本文讲的是Java实现web在线预览office文档 ...

  8. C#字符串(Sring)操作

    //字符串访问            //string s = "ABCD";            //Console.WriteLine(s[0]);//第0位字符       ...

  9. 湖南大学ACM程序设计新生杯大赛(同步赛)L - Liao Han

    题目描述 Small koala special love LiaoHan (of course is very handsome boys), one day she saw N (N<1e1 ...

  10. 最短路——spfa

    适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一 ...