llvm中如何利用分支概率和基本块频率估计

摘要:
从基本块A到所有后续基本块的控制流的概率之和为1。基本块频率是指程序控制流图中任何基本块的执行次数。这两种类型的信息都可以通过静态分析获得。

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() << "
");
  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::stringszInfo;
raw_fd_ostreamS("machinBranchProbs.txt",szInfo,raw_fd_ostream::F_Append);
for(MachineFunction::iteratorBI=F.begin(),BE=F.end(); BI!=BE;++BI){
 MachineBasicBlock*MBB=BI;
    for(MachineBasicBlock::const_succ_iteratorSI=MBB->succ_begin(),EI=MBB->succ_end();SI!=EI;++SI){
     MachineBasicBlock*mBlock=*SI;
MBPI->printEdgeProbability(S<<"",MBB,mBlock);
}
}
S.close();
//打印基本块频率信息
raw_fd_ostreamS1("machinBlockFreq.txt",szInfo,raw_fd_ostream::F_Append);
if(MBFI)MBFI->print(S1);;
S1.close();
  ...
returnfalse;
}

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中如何利用分支概率和基本块频率估计》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇BI笔记之Cube增量处理的一个场景的处理方案地址族与数据序列 (转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

运行bat时隐藏cmd窗口

这种方法在击球时仍然闪烁。隐藏和运行蝙蝠文件的几种方法Bat文件是在Windows系统中以命令行模式执行一个或多个命令的批处理文件。然而,大多数脚本在运行时都会弹出黑色背景的DOS窗口,这会让许多用户无所适从,甚至会错误关闭正在运行的窗口。...

Centos7 挂载

1.Mount命令:Mount语法格式:Mount Mount设备文件信息Mount point(目录)注意:装载点(目录)必须有一个装载CD-ROM驱动器:Mount/dev/cdrom/mnt 2.卸载命令:umount语法格式:umountmount point(directory)3.查看磁盘装载状态/查看磁盘使用情况df4。存储设备通电时自动装载#...

电脑不识别USB blaster驱动问题

电脑不识别USB blaster,如下图: 解决办法:手动更新...

如何更改SQL Server2008默认数据库的存储路径

1.在安装SQlServer时,修改路径:当然,也可以修改共享函数目录和实例根目录。但是,我不知道共享函数目录和实例根目录是什么。...

Uni-app v-on监听事件

使用标记上的v-on监视事件。缩写为@click common click events方法:方法:{Focus(){console.log;},blur(){console.log;},confirm(){console.log;},click(){console.log;},tap(){console.log;},longpress(){console....

开源项目推荐:Qt有关的GitHub/Gitee开源项目

https://www.froglogic.com/windeployqthttps://doc.qt.io/Qt-5/windows部署。htmlhttps://wiki.qt.io/Deploy_an_Application_on_Windowshttps://github.com/lucasg/Dependencieshttp://www.depend...