Skip to content

Commit c2f791d

Browse files
committedJul 13, 2016
[BFI] Add new LazyBFI analysis pass
Summary: This is necessary for D21771. In order to add the hotness attribute to optimization remarks we need BFI to be available in all passes that emit optimization remarks. However we don't want to pay for computing BFI unless the hotness attribute is requested. This is achieved by making BFI lazy at the very high-level through a new analysis pass -- BFI is not calculated unless requested. I am adding a test to check the laziness under D21771 where the first user of the analysis is added. Reviewers: hfinkel, dexonsmith, davidxl Subscribers: davidxl, dexonsmith, llvm-commits Differential Revision: http://reviews.llvm.org/D22141 llvm-svn: 275250
1 parent 90a9704 commit c2f791d

File tree

8 files changed

+205
-0
lines changed

8 files changed

+205
-0
lines changed
 

‎llvm/include/llvm/Analysis/BlockFrequencyInfo.h

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class BlockFrequencyInfo {
4343

4444
BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS);
4545

46+
~BlockFrequencyInfo();
47+
4648
const Function *getFunction() const;
4749
const BranchProbabilityInfo *getBPI() const;
4850
void view() const;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The
11+
// difference is that with this pass the block frequencies are not computed when
12+
// the analysis pass is executed but rather when the BFI results is explicitly
13+
// requested by the analysis client.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H
18+
#define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H
19+
20+
#include "llvm/Analysis/BlockFrequencyInfo.h"
21+
#include "llvm/Pass.h"
22+
23+
namespace llvm {
24+
class AnalysisUsage;
25+
class BranchProbabilityInfo;
26+
class Function;
27+
class LoopInfo;
28+
29+
/// \brief This is an alternative analysis pass to
30+
/// BlockFrequencyInfoWrapperPass. The difference is that with this pass the
31+
/// block frequencies are not computed when the analysis pass is executed but
32+
/// rather when the BFI results is explicitly requested by the analysis client.
33+
///
34+
/// There are some additional requirements for any client pass that wants to use
35+
/// the analysis:
36+
///
37+
/// 1. The pass needs to initialize dependent passes with:
38+
///
39+
/// INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
40+
///
41+
/// 2. Similarly, getAnalysisUsage should call:
42+
///
43+
/// LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU)
44+
///
45+
/// 3. The computed BFI should be requested with
46+
/// getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() before either LoopInfo
47+
/// or BPI could be invalidated for example by changing the CFG.
48+
///
49+
/// Note that it is expected that we wouldn't need this functionality for the
50+
/// new PM since with the new PM, analyses are executed on demand.
51+
class LazyBlockFrequencyInfoPass : public FunctionPass {
52+
53+
/// Wraps a BFI to allow lazy computation of the block frequencies.
54+
///
55+
/// A pass that only conditionally uses BFI can uncondtionally require the
56+
/// analysis without paying for the overhead if BFI doesn't end up being used.
57+
class LazyBlockFrequencyInfo {
58+
public:
59+
LazyBlockFrequencyInfo()
60+
: Calculated(false), F(nullptr), BPI(nullptr), LI(nullptr) {}
61+
62+
/// Set up the per-function input.
63+
void setAnalysis(const Function *F, const BranchProbabilityInfo *BPI,
64+
const LoopInfo *LI) {
65+
this->F = F;
66+
this->BPI = BPI;
67+
this->LI = LI;
68+
}
69+
70+
/// Retrieve the BFI with the block frequencies computed.
71+
BlockFrequencyInfo &getCalculated() {
72+
if (!Calculated) {
73+
assert(F && BPI && LI && "call setAnalysis");
74+
BFI.calculate(*F, *BPI, *LI);
75+
Calculated = true;
76+
}
77+
return BFI;
78+
}
79+
80+
const BlockFrequencyInfo &getCalculated() const {
81+
return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated();
82+
}
83+
84+
void releaseMemory() {
85+
BFI.releaseMemory();
86+
Calculated = false;
87+
setAnalysis(nullptr, nullptr, nullptr);
88+
}
89+
90+
private:
91+
BlockFrequencyInfo BFI;
92+
bool Calculated;
93+
const Function *F;
94+
const BranchProbabilityInfo *BPI;
95+
const LoopInfo *LI;
96+
};
97+
98+
LazyBlockFrequencyInfo LBFI;
99+
100+
public:
101+
static char ID;
102+
103+
LazyBlockFrequencyInfoPass();
104+
105+
/// \brief Compute and return the block frequencies.
106+
BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); }
107+
108+
/// \brief Compute and return the block frequencies.
109+
const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); }
110+
111+
void getAnalysisUsage(AnalysisUsage &AU) const override;
112+
113+
/// Helper for client passes to set up the analysis usage on behalf of this
114+
/// pass.
115+
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU);
116+
117+
bool runOnFunction(Function &F) override;
118+
void releaseMemory() override;
119+
void print(raw_ostream &OS, const Module *M) const override;
120+
};
121+
122+
/// \brief Helper for client passes to initialize dependent passes for LBFI.
123+
void initializeLazyBFIPassPass(PassRegistry &Registry);
124+
}
125+
#endif

‎llvm/include/llvm/InitializePasses.h

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ void initializeIntervalPartitionPass(PassRegistry&);
160160
void initializeJumpThreadingPass(PassRegistry&);
161161
void initializeLCSSAWrapperPassPass(PassRegistry &);
162162
void initializeLegacyLICMPassPass(PassRegistry&);
163+
void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&);
163164
void initializeLazyValueInfoWrapperPassPass(PassRegistry&);
164165
void initializeLintPass(PassRegistry&);
165166
void initializeLiveDebugValuesPass(PassRegistry&);

‎llvm/lib/Analysis/Analysis.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
5454
initializeIVUsersPass(Registry);
5555
initializeInstCountPass(Registry);
5656
initializeIntervalPartitionPass(Registry);
57+
initializeLazyBlockFrequencyInfoPassPass(Registry);
5758
initializeLazyValueInfoWrapperPassPass(Registry);
5859
initializeLintPass(Registry);
5960
initializeLoopInfoWrapperPassPass(Registry);

‎llvm/lib/Analysis/BlockFrequencyInfo.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ BlockFrequencyInfo &BlockFrequencyInfo::operator=(BlockFrequencyInfo &&RHS) {
129129
return *this;
130130
}
131131

132+
// Explicitly define the default constructor otherwise it would be implicitly
133+
// defined at the first ODR-use which is the BFI member in the
134+
// LazyBlockFrequencyInfo header. The dtor needs the BlockFrequencyInfoImpl
135+
// template instantiated which is not available in the header.
136+
BlockFrequencyInfo::~BlockFrequencyInfo() {}
137+
132138
void BlockFrequencyInfo::calculate(const Function &F,
133139
const BranchProbabilityInfo &BPI,
134140
const LoopInfo &LI) {

‎llvm/lib/Analysis/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ add_llvm_library(LLVMAnalysis
3737
Interval.cpp
3838
IntervalPartition.cpp
3939
IteratedDominanceFrontier.cpp
40+
LazyBlockFrequencyInfo.cpp
4041
LazyCallGraph.cpp
4142
LazyValueInfo.cpp
4243
Lint.cpp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===- LazyBlockFrequencyInfo.cpp - Lazy Block Frequency Analysis ---------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The
11+
// difference is that with this pass the block frequencies are not computed when
12+
// the analysis pass is executed but rather when the BFI results is explicitly
13+
// requested by the analysis client.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18+
#include "llvm/Analysis/BranchProbabilityInfo.h"
19+
#include "llvm/Analysis/LoopInfo.h"
20+
21+
using namespace llvm;
22+
23+
#define DEBUG_TYPE "lazy-block-freq"
24+
25+
INITIALIZE_PASS_BEGIN(LazyBlockFrequencyInfoPass, DEBUG_TYPE,
26+
"Lazy Block Frequency Analysis", true, true)
27+
INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
28+
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
29+
INITIALIZE_PASS_END(LazyBlockFrequencyInfoPass, DEBUG_TYPE,
30+
"Lazy Block Frequency Analysis", true, true)
31+
32+
char LazyBlockFrequencyInfoPass::ID = 0;
33+
34+
LazyBlockFrequencyInfoPass::LazyBlockFrequencyInfoPass() : FunctionPass(ID) {
35+
initializeLazyBlockFrequencyInfoPassPass(*PassRegistry::getPassRegistry());
36+
}
37+
38+
void LazyBlockFrequencyInfoPass::print(raw_ostream &OS, const Module *) const {
39+
LBFI.getCalculated().print(OS);
40+
}
41+
42+
void LazyBlockFrequencyInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
43+
AU.addRequired<BranchProbabilityInfoWrapperPass>();
44+
AU.addRequired<LoopInfoWrapperPass>();
45+
AU.setPreservesAll();
46+
}
47+
48+
void LazyBlockFrequencyInfoPass::releaseMemory() { LBFI.releaseMemory(); }
49+
50+
bool LazyBlockFrequencyInfoPass::runOnFunction(Function &F) {
51+
BranchProbabilityInfo &BPI =
52+
getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
53+
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
54+
LBFI.setAnalysis(&F, &BPI, &LI);
55+
return false;
56+
}
57+
58+
void LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AnalysisUsage &AU) {
59+
AU.addRequired<BranchProbabilityInfoWrapperPass>();
60+
AU.addRequired<LazyBlockFrequencyInfoPass>();
61+
AU.addRequired<LoopInfoWrapperPass>();
62+
}
63+
64+
void llvm::initializeLazyBFIPassPass(PassRegistry &Registry) {
65+
INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass);
66+
INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass);
67+
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
68+
}

‎llvm/test/Analysis/BlockFrequencyInfo/basic.ll

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: opt < %s -analyze -block-freq | FileCheck %s
2+
; RUN: opt < %s -analyze -lazy-block-freq | FileCheck %s
23
; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
34

45
define i32 @test1(i32 %i, i32* %a) {

0 commit comments

Comments
 (0)
Please sign in to comment.