Index: include/llvm/Analysis/LazyBlockFrequencyInfo.h =================================================================== --- include/llvm/Analysis/LazyBlockFrequencyInfo.h +++ include/llvm/Analysis/LazyBlockFrequencyInfo.h @@ -20,6 +20,7 @@ #include "llvm/Analysis/BlockFrequencyInfo.h" #include "llvm/Analysis/LazyBranchProbabilityInfo.h" #include "llvm/Pass.h" +#include namespace llvm { class AnalysisUsage; @@ -31,12 +32,18 @@ /// /// 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. -template +template class LazyBlockFrequencyInfo { public: - LazyBlockFrequencyInfo() - : Calculated(false), F(nullptr), BPIPass(nullptr), LI(nullptr) {} + typedef std::function + CalculateBPI; + + LazyBlockFrequencyInfo(CalculateBPI calculateBPI) + : Calculated(false), F(nullptr), BPIPass(nullptr), + calculateBPI(calculateBPI), LI(nullptr) {} /// Set up the per-function input. void setAnalysis(const FunctionT *F, LazyBranchProbabilityInfoPassT *BPIPass, @@ -50,7 +57,7 @@ BlockFrequencyInfoT &getCalculated() { if (!Calculated) { assert(F && BPIPass && LI && "call setAnalysis"); - BFI.calculate(*F, BPIPass->getBPI(), *LI); + BFI.calculate(*F, calculateBPI(BPIPass), *LI); Calculated = true; } return BFI; @@ -71,6 +78,7 @@ bool Calculated; const FunctionT *F; LazyBranchProbabilityInfoPassT *BPIPass; + CalculateBPI calculateBPI; const LoopInfoT *LI; }; @@ -99,8 +107,8 @@ class LazyBlockFrequencyInfoPass : public FunctionPass { private: - LazyBlockFrequencyInfo + LazyBlockFrequencyInfo LBFI; public: Index: include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h =================================================================== --- /dev/null +++ include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h @@ -0,0 +1,84 @@ +///===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*--===// +/// +/// The LLVM Compiler Infrastructure +/// +/// This file is distributed under the University of Illinois Open Source +/// License. See LICENSE.TXT for details. +/// +///===---------------------------------------------------------------------===// +/// \file +/// This is an alternative analysis pass to MachineBlockFrequencyInfo. The +/// difference is that with this pass the block frequencies are not computed +/// when the analysis pass is executed but rather when the BFI result is +/// explicitly requested by the analysis client. +/// +///===---------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LAZYMACHINEBLOCKFREQUENCYINFO_H +#define LLVM_ANALYSIS_LAZYMACHINEBLOCKFREQUENCYINFO_H + +#include "llvm/Analysis/LazyBlockFrequencyInfo.h" +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" +#include "llvm/CodeGen/MachineLoopInfo.h" + +namespace llvm { +/// \brief This is an alternative analysis pass to MachineBlockFrequencyInfo. +/// The difference is that with this pass, the block frequencies are not +/// computed when the analysis pass is executed but rather when the BFI result +/// 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(LazyMachineBFIPass) +/// +/// 2. Similarly, getAnalysisUsage should call: +/// +/// LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(AU) +/// +/// 3. The computed MachineBFI should be requested with +/// getAnalysis().getBFI() before +/// MachineLoopInfo 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 LazyMachineBlockFrequencyInfoPass : public MachineFunctionPass { +private: + /// \brief Machine BPI is an immutable pass, no need to use it lazily. + LazyBlockFrequencyInfo + LMBFI; + +public: + static char ID; + + LazyMachineBlockFrequencyInfoPass(); + + /// \brief Compute and return the block frequencies. + MachineBlockFrequencyInfo &getBFI() { return LMBFI.getCalculated(); } + + /// \brief Compute and return the block frequencies. + const MachineBlockFrequencyInfo &getBFI() const { + return LMBFI.getCalculated(); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + /// Helper for client passes to set up the analysis usage on behalf of this + /// pass. + static void getLazyMachineBFIAnalysisUsage(AnalysisUsage &AU); + + bool runOnMachineFunction(MachineFunction &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 LMBFI. +void initializeLazyMachineBFIPassPass(PassRegistry &Registry); +} +#endif Index: include/llvm/CodeGen/MachineBlockFrequencyInfo.h =================================================================== --- include/llvm/CodeGen/MachineBlockFrequencyInfo.h +++ include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -23,6 +23,7 @@ class MachineBasicBlock; class MachineBranchProbabilityInfo; +class MachineLoopInfo; template class BlockFrequencyInfoImpl; /// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation @@ -42,6 +43,11 @@ bool runOnMachineFunction(MachineFunction &F) override; + /// calculate - compute block frequency info for the given function. + void calculate(const MachineFunction &F, + const MachineBranchProbabilityInfo &MBPI, + const MachineLoopInfo &MLI); + void releaseMemory() override; /// getblockFreq - Return block frequency. Return 0 if we don't have the Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -175,6 +175,7 @@ void initializeLegacyLICMPassPass(PassRegistry&); void initializeLegacyLoopSinkPassPass(PassRegistry&); void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&); +void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyValueInfoWrapperPassPass(PassRegistry&); void initializeLegalizerPass(PassRegistry&); Index: lib/Analysis/LazyBlockFrequencyInfo.cpp =================================================================== --- lib/Analysis/LazyBlockFrequencyInfo.cpp +++ lib/Analysis/LazyBlockFrequencyInfo.cpp @@ -31,7 +31,11 @@ char LazyBlockFrequencyInfoPass::ID = 0; -LazyBlockFrequencyInfoPass::LazyBlockFrequencyInfoPass() : FunctionPass(ID) { +LazyBlockFrequencyInfoPass::LazyBlockFrequencyInfoPass() + : FunctionPass(ID), + LBFI([](LazyBranchProbabilityInfoPass *P) -> BranchProbabilityInfo & { + return P->getBPI(); + }) { initializeLazyBlockFrequencyInfoPassPass(*PassRegistry::getPassRegistry()); } Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -37,6 +37,7 @@ InterleavedAccessPass.cpp IntrinsicLowering.cpp LatencyPriorityQueue.cpp + LazyMachineBlockFrequencyInfo.cpp LexicalScopes.cpp LiveDebugValues.cpp LiveDebugVariables.cpp Index: lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp =================================================================== --- /dev/null +++ lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp @@ -0,0 +1,78 @@ +///===- LazyMachineBlockFrequencyInfo.cpp - Lazy Machine Block Frequency --===// +/// +/// The LLVM Compiler Infrastructure +/// +/// This file is distributed under the University of Illinois Open Source +/// License. See LICENSE.TXT for details. +/// +///===---------------------------------------------------------------------===// +/// \file +/// This is an alternative analysis pass to MachineBlockFrequencyInfo. The +/// difference is that with this pass the block frequencies are not computed +/// when the analysis pass is executed but rather when the BFI result is +/// explicitly requested by the analysis client. +/// +///===---------------------------------------------------------------------===// + +#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" + +using namespace llvm; + +#define DEBUG_TYPE "lazy-machine-block-freq" + +INITIALIZE_PASS_BEGIN(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE, + "Lazy Machine Block Frequency Analysis", true, true) +INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_END(LazyMachineBlockFrequencyInfoPass, DEBUG_TYPE, + "Lazy Machine Block Frequency Analysis", true, true) + +char LazyMachineBlockFrequencyInfoPass::ID = 0; + +LazyMachineBlockFrequencyInfoPass::LazyMachineBlockFrequencyInfoPass() + : MachineFunctionPass(ID), + /// Machine BPI is an immutable pass, so this is effectively just the + /// identity function. + LMBFI([](MachineBranchProbabilityInfo *I) + -> MachineBranchProbabilityInfo & { return *I; }) { + initializeLazyMachineBlockFrequencyInfoPassPass( + *PassRegistry::getPassRegistry()); +} + +void LazyMachineBlockFrequencyInfoPass::print(raw_ostream &OS, + const Module *M) const { + LMBFI.getCalculated().print(OS, M); +} + +void LazyMachineBlockFrequencyInfoPass::getAnalysisUsage( + AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); +} + +void LazyMachineBlockFrequencyInfoPass::releaseMemory() { + LMBFI.releaseMemory(); +} + +bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction( + MachineFunction &MF) { + auto &BPIPass = getAnalysis(); + auto &LI = getAnalysis(); + LMBFI.setAnalysis(&MF, &BPIPass, &LI); + return false; +} + +void LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage( + AnalysisUsage &AU) { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); +} + +void llvm::initializeLazyMachineBFIPassPass(PassRegistry &Registry) { + INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass); + INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo); + INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo); +} Index: lib/CodeGen/MachineBlockFrequencyInfo.cpp =================================================================== --- lib/CodeGen/MachineBlockFrequencyInfo.cpp +++ lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -170,10 +170,9 @@ MachineFunctionPass::getAnalysisUsage(AU); } -bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { - MachineBranchProbabilityInfo &MBPI = - getAnalysis(); - MachineLoopInfo &MLI = getAnalysis(); +void MachineBlockFrequencyInfo::calculate( + const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI, + const MachineLoopInfo &MLI) { if (!MBFI) MBFI.reset(new ImplType); MBFI->calculate(F, MBPI, MLI); @@ -184,6 +183,13 @@ view(); } #endif +} + +bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { + MachineBranchProbabilityInfo &MBPI = + getAnalysis(); + MachineLoopInfo &MLI = getAnalysis(); + calculate(F, MBPI, MLI); return false; } Index: lib/CodeGen/MachineOptimizationRemarkEmitter.cpp =================================================================== --- lib/CodeGen/MachineOptimizationRemarkEmitter.cpp +++ lib/CodeGen/MachineOptimizationRemarkEmitter.cpp @@ -14,7 +14,7 @@ ///===---------------------------------------------------------------------===// #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" -#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/LLVMContext.h" @@ -64,7 +64,7 @@ MachineBlockFrequencyInfo *MBFI; if (MF.getFunction()->getContext().getDiagnosticHotnessRequested()) - MBFI = &getAnalysis(); + MBFI = &getAnalysis().getBFI(); else MBFI = nullptr; @@ -74,7 +74,7 @@ void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( AnalysisUsage &AU) const { - AU.addRequired(); + LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(AU); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -85,6 +85,6 @@ INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, false, true) -INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) +INITIALIZE_PASS_DEPENDENCY(LazyMachineBFIPass) INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, false, true)