diff --git a/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h b/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h index 08b9c6493c0c..9a8f1ad8e909 100644 --- a/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h +++ b/llvm/include/llvm/Analysis/LazyBlockFrequencyInfo.h @@ -50,7 +50,8 @@ public: BlockFrequencyInfoT &getCalculated() { if (!Calculated) { assert(F && BPIPass && LI && "call setAnalysis"); - BFI.calculate(*F, BPIPass->getBPI(), *LI); + BFI.calculate( + *F, BPIPassTrait::getBPI(BPIPass), *LI); Calculated = true; } return BFI; diff --git a/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h index c76fa1e819ae..067d7ebfd1f5 100644 --- a/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h +++ b/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h @@ -105,5 +105,17 @@ public: /// \brief Helper for client passes to initialize dependent passes for LBPI. void initializeLazyBPIPassPass(PassRegistry &Registry); + +/// \brief Simple trait class that provides a mapping between BPI passes and the +/// corresponding BPInfo. +template struct BPIPassTrait { + static PassT &getBPI(PassT *P) { return *P; } +}; + +template <> struct BPIPassTrait { + static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) { + return P->getBPI(); + } +}; } #endif diff --git a/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h b/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h new file mode 100644 index 000000000000..041b96db35f2 --- /dev/null +++ b/llvm/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h @@ -0,0 +1,83 @@ +///===- 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 diff --git a/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h index acd84088f1e5..ead0012e700f 100644 --- a/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h +++ b/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -23,6 +23,7 @@ namespace llvm { class MachineBasicBlock; class MachineBranchProbabilityInfo; +class MachineLoopInfo; template class BlockFrequencyInfoImpl; /// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation @@ -42,6 +43,11 @@ public: 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 diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index d5e544e5cc6a..d30d66967ecc 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -175,6 +175,7 @@ void initializeLCSSAVerificationPassPass(PassRegistry&); void initializeLegacyLICMPassPass(PassRegistry&); void initializeLegacyLoopSinkPassPass(PassRegistry&); void initializeLazyBranchProbabilityInfoPassPass(PassRegistry&); +void initializeLazyMachineBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&); void initializeLazyValueInfoWrapperPassPass(PassRegistry&); void initializeLegalizerPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index a9a3d85f3c26..817d4e89cf12 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -37,6 +37,7 @@ add_llvm_library(LLVMCodeGen InterleavedAccessPass.cpp IntrinsicLowering.cpp LatencyPriorityQueue.cpp + LazyMachineBlockFrequencyInfo.cpp LexicalScopes.cpp LiveDebugValues.cpp LiveDebugVariables.cpp diff --git a/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp new file mode 100644 index 000000000000..34611f8064d7 --- /dev/null +++ b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp @@ -0,0 +1,74 @@ +///===- 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) { + 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); +} diff --git a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp index c496e3226e5e..557b5f8824d5 100644 --- a/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp +++ b/llvm/lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -172,10 +172,9 @@ void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const { 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 @@ bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { F.getName().equals(ViewBlockFreqFuncName))) { view(); } +} + +bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { + MachineBranchProbabilityInfo &MBPI = + getAnalysis(); + MachineLoopInfo &MLI = getAnalysis(); + calculate(F, MBPI, MLI); return false; } diff --git a/llvm/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp b/llvm/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp index 0fc286969ebc..b76e75a4bd4d 100644 --- a/llvm/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp +++ b/llvm/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 @@ bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( MachineBlockFrequencyInfo *MBFI; if (MF.getFunction()->getContext().getDiagnosticHotnessRequested()) - MBFI = &getAnalysis(); + MBFI = &getAnalysis().getBFI(); else MBFI = nullptr; @@ -74,7 +74,7 @@ bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction( void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( AnalysisUsage &AU) const { - AU.addRequired(); + LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(AU); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -85,6 +85,6 @@ static const char ore_name[] = "Machine Optimization Remark Emitter"; 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)