diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Analysis/BlockFrequencyInfo.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h | 125 | ||||
| -rw-r--r-- | llvm/include/llvm/InitializePasses.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Analysis/Analysis.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Analysis/BlockFrequencyInfo.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Analysis/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Analysis/LazyBlockFrequencyInfo.cpp | 68 | ||||
| -rw-r--r-- | llvm/test/Analysis/BlockFrequencyInfo/basic.ll | 1 |
8 files changed, 205 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/BlockFrequencyInfo.h b/llvm/include/llvm/Analysis/BlockFrequencyInfo.h index ed473abf3b3..7d48dfc9121 100644 --- a/llvm/include/llvm/Analysis/BlockFrequencyInfo.h +++ b/llvm/include/llvm/Analysis/BlockFrequencyInfo.h @@ -43,6 +43,8 @@ public: BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS); + ~BlockFrequencyInfo(); + const Function *getFunction() const; const BranchProbabilityInfo *getBPI() const; void view() const; diff --git a/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h b/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h new file mode 100644 index 00000000000..a2d24bb9eb8 --- /dev/null +++ b/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h @@ -0,0 +1,125 @@ +//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The +// difference is that with this pass the block frequencies are not computed when +// the analysis pass is executed but rather when the BFI results is explicitly +// requested by the analysis client. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H +#define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H + +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Pass.h" + +namespace llvm { +class AnalysisUsage; +class BranchProbabilityInfo; +class Function; +class LoopInfo; + +/// \brief This is an alternative analysis pass to +/// BlockFrequencyInfoWrapperPass. The difference is that with this pass the +/// block frequencies are not computed when the analysis pass is executed but +/// rather when the BFI results is explicitly requested by the analysis client. +/// +/// There are some additional requirements for any client pass that wants to use +/// the analysis: +/// +/// 1. The pass needs to initialize dependent passes with: +/// +/// INITIALIZE_PASS_DEPENDENCY(LazyBFIPass) +/// +/// 2. Similarly, getAnalysisUsage should call: +/// +/// LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU) +/// +/// 3. The computed BFI should be requested with +/// getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() before either LoopInfo +/// or BPI could be invalidated for example by changing the CFG. +/// +/// Note that it is expected that we wouldn't need this functionality for the +/// new PM since with the new PM, analyses are executed on demand. +class LazyBlockFrequencyInfoPass : public FunctionPass { + + /// Wraps a BFI to allow lazy computation of the block frequencies. + /// + /// A pass that only conditionally uses BFI can uncondtionally require the + /// analysis without paying for the overhead if BFI doesn't end up being used. + class LazyBlockFrequencyInfo { + public: + LazyBlockFrequencyInfo() + : Calculated(false), F(nullptr), BPI(nullptr), LI(nullptr) {} + + /// Set up the per-function input. + void setAnalysis(const Function *F, const BranchProbabilityInfo *BPI, + const LoopInfo *LI) { + this->F = F; + this->BPI = BPI; + this->LI = LI; + } + + /// Retrieve the BFI with the block frequencies computed. + BlockFrequencyInfo &getCalculated() { + if (!Calculated) { + assert(F && BPI && LI && "call setAnalysis"); + BFI.calculate(*F, *BPI, *LI); + Calculated = true; + } + return BFI; + } + + const BlockFrequencyInfo &getCalculated() const { + return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated(); + } + + void releaseMemory() { + BFI.releaseMemory(); + Calculated = false; + setAnalysis(nullptr, nullptr, nullptr); + } + + private: + BlockFrequencyInfo BFI; + bool Calculated; + const Function *F; + const BranchProbabilityInfo *BPI; + const LoopInfo *LI; + }; + + LazyBlockFrequencyInfo LBFI; + +public: + static char ID; + + LazyBlockFrequencyInfoPass(); + + /// \brief Compute and return the block frequencies. + BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); } + + /// \brief Compute and return the block frequencies. + const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + /// Helper for client passes to set up the analysis usage on behalf of this + /// pass. + static void getLazyBFIAnalysisUsage(AnalysisUsage &AU); + + bool runOnFunction(Function &F) override; + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M) const override; +}; + +/// \brief Helper for client passes to initialize dependent passes for LBFI. +void initializeLazyBFIPassPass(PassRegistry &Registry); +} +#endif diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 12de6310c5f..59ee09432ee 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -160,6 +160,7 @@ void initializeIntervalPartitionPass(PassRegistry&); void initializeJumpThreadingPass(PassRegistry&); void initializeLCSSAWrapperPassPass(PassRegistry &); void initializeLegacyLICMPassPass(PassRegistry&); +void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyValueInfoWrapperPassPass(PassRegistry&); void initializeLintPass(PassRegistry&); void initializeLiveDebugValuesPass(PassRegistry&); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 099ac15245c..2bcfe402e68 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -54,6 +54,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeIVUsersPass(Registry); initializeInstCountPass(Registry); initializeIntervalPartitionPass(Registry); + initializeLazyBlockFrequencyInfoPassPass(Registry); initializeLazyValueInfoWrapperPassPass(Registry); initializeLintPass(Registry); initializeLoopInfoWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/BlockFrequencyInfo.cpp b/llvm/lib/Analysis/BlockFrequencyInfo.cpp index de1c8553c93..1dd8f4fdfcf 100644 --- a/llvm/lib/Analysis/BlockFrequencyInfo.cpp +++ b/llvm/lib/Analysis/BlockFrequencyInfo.cpp @@ -129,6 +129,12 @@ BlockFrequencyInfo &BlockFrequencyInfo::operator=(BlockFrequencyInfo &&RHS) { return *this; } +// Explicitly define the default constructor otherwise it would be implicitly +// defined at the first ODR-use which is the BFI member in the +// LazyBlockFrequencyInfo header. The dtor needs the BlockFrequencyInfoImpl +// template instantiated which is not available in the header. +BlockFrequencyInfo::~BlockFrequencyInfo() {} + void BlockFrequencyInfo::calculate(const Function &F, const BranchProbabilityInfo &BPI, const LoopInfo &LI) { diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt index ee9edd8b01a..5c6011d77ce 100644 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -37,6 +37,7 @@ add_llvm_library(LLVMAnalysis Interval.cpp IntervalPartition.cpp IteratedDominanceFrontier.cpp + LazyBlockFrequencyInfo.cpp LazyCallGraph.cpp LazyValueInfo.cpp Lint.cpp diff --git a/llvm/lib/Analysis/LazyBlockFrequencyInfo.cpp b/llvm/lib/Analysis/LazyBlockFrequencyInfo.cpp new file mode 100644 index 00000000000..7debfde87d2 --- /dev/null +++ b/llvm/lib/Analysis/LazyBlockFrequencyInfo.cpp @@ -0,0 +1,68 @@ +//===- LazyBlockFrequencyInfo.cpp - Lazy Block Frequency Analysis ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass. The +// difference is that with this pass the block frequencies are not computed when +// the analysis pass is executed but rather when the BFI results is explicitly +// requested by the analysis client. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/LazyBlockFrequencyInfo.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/LoopInfo.h" + +using namespace llvm; + +#define DEBUG_TYPE "lazy-block-freq" + +INITIALIZE_PASS_BEGIN(LazyBlockFrequencyInfoPass, DEBUG_TYPE, + "Lazy Block Frequency Analysis", true, true) +INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_END(LazyBlockFrequencyInfoPass, DEBUG_TYPE, + "Lazy Block Frequency Analysis", true, true) + +char LazyBlockFrequencyInfoPass::ID = 0; + +LazyBlockFrequencyInfoPass::LazyBlockFrequencyInfoPass() : FunctionPass(ID) { + initializeLazyBlockFrequencyInfoPassPass(*PassRegistry::getPassRegistry()); +} + +void LazyBlockFrequencyInfoPass::print(raw_ostream &OS, const Module *) const { + LBFI.getCalculated().print(OS); +} + +void LazyBlockFrequencyInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<BranchProbabilityInfoWrapperPass>(); + AU.addRequired<LoopInfoWrapperPass>(); + AU.setPreservesAll(); +} + +void LazyBlockFrequencyInfoPass::releaseMemory() { LBFI.releaseMemory(); } + +bool LazyBlockFrequencyInfoPass::runOnFunction(Function &F) { + BranchProbabilityInfo &BPI = + getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI(); + LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); + LBFI.setAnalysis(&F, &BPI, &LI); + return false; +} + +void LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AnalysisUsage &AU) { + AU.addRequired<BranchProbabilityInfoWrapperPass>(); + AU.addRequired<LazyBlockFrequencyInfoPass>(); + AU.addRequired<LoopInfoWrapperPass>(); +} + +void llvm::initializeLazyBFIPassPass(PassRegistry &Registry) { + INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass); + INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass); + INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +} diff --git a/llvm/test/Analysis/BlockFrequencyInfo/basic.ll b/llvm/test/Analysis/BlockFrequencyInfo/basic.ll index 44bfc36a711..a957adc6502 100644 --- a/llvm/test/Analysis/BlockFrequencyInfo/basic.ll +++ b/llvm/test/Analysis/BlockFrequencyInfo/basic.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -analyze -block-freq | FileCheck %s +; RUN: opt < %s -analyze -lazy-block-freq | FileCheck %s ; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s define i32 @test1(i32 %i, i32* %a) { |

