Index: llvm/trunk/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h +++ llvm/trunk/include/llvm/CodeGen/LazyMachineBlockFrequencyInfo.h @@ -17,9 +17,9 @@ #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/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" namespace llvm { @@ -28,30 +28,30 @@ /// 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. +/// This works by checking querying if MBFI is available and otherwise +/// generating MBFI on the fly. In this case the passes required for (LI, DT) +/// are also queried before being computed on the fly. /// /// 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; + /// If generated on the fly this own the instance. + mutable std::unique_ptr OwnedMBFI; + + /// If generated on the fly this own the instance. + mutable std::unique_ptr OwnedMLI; + + /// If generated on the fly this own the instance. + mutable std::unique_ptr OwnedMDT; + + /// The function. + MachineFunction *MF = nullptr; + + /// \brief Calculate MBFI and all other analyses that's not available and + /// required by BFI. + MachineBlockFrequencyInfo &calculateIfNotAvailable() const; public: static char ID; @@ -59,25 +59,18 @@ LazyMachineBlockFrequencyInfoPass(); /// \brief Compute and return the block frequencies. - MachineBlockFrequencyInfo &getBFI() { return LMBFI.getCalculated(); } + MachineBlockFrequencyInfo &getBFI() { return calculateIfNotAvailable(); } /// \brief Compute and return the block frequencies. const MachineBlockFrequencyInfo &getBFI() const { - return LMBFI.getCalculated(); + return calculateIfNotAvailable(); } 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: llvm/trunk/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp +++ llvm/trunk/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp @@ -37,38 +37,61 @@ void LazyMachineBlockFrequencyInfoPass::print(raw_ostream &OS, const Module *M) const { - LMBFI.getCalculated().print(OS, M); + getBFI().print(OS, M); } void LazyMachineBlockFrequencyInfoPass::getAnalysisUsage( AnalysisUsage &AU) const { AU.addRequired(); - AU.addRequired(); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } void LazyMachineBlockFrequencyInfoPass::releaseMemory() { - LMBFI.releaseMemory(); + OwnedMBFI.reset(); + OwnedMLI.reset(); + OwnedMDT.reset(); +} + +MachineBlockFrequencyInfo & +LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const { + auto *MBFI = getAnalysisIfAvailable(); + if (MBFI) { + DEBUG(dbgs() << "MachineBlockFrequencyInfo is available\n"); + return *MBFI; + } + + auto &MBPI = getAnalysis(); + auto *MLI = getAnalysisIfAvailable(); + auto *MDT = getAnalysisIfAvailable(); + DEBUG(dbgs() << "Building MachineBlockFrequencyInfo on the fly\n"); + DEBUG(if (MLI) dbgs() << "LoopInfo is available\n"); + + if (!MLI) { + DEBUG(dbgs() << "Building LoopInfo on the fly\n"); + // First create a dominator tree. + DEBUG(if (MDT) dbgs() << "DominatorTree is available\n"); + + if (!MDT) { + DEBUG(dbgs() << "Building DominatorTree on the fly\n"); + OwnedMDT = make_unique(); + OwnedMDT->getBase().recalculate(*MF); + MDT = OwnedMDT.get(); + } + + // Generate LoopInfo from it. + OwnedMLI = make_unique(); + OwnedMLI->getBase().analyze(MDT->getBase()); + MLI = OwnedMLI.get(); + } + + OwnedMBFI = make_unique(); + OwnedMBFI->calculate(*MF, MBPI, *MLI); + return *OwnedMBFI.get(); } bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction( - MachineFunction &MF) { - auto &BPIPass = getAnalysis(); - auto &LI = getAnalysis(); - LMBFI.setAnalysis(&MF, &BPIPass, &LI); + MachineFunction &F) { + MF = &F; 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: llvm/trunk/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp +++ llvm/trunk/lib/CodeGen/MachineOptimizationRemarkEmitter.cpp @@ -74,7 +74,7 @@ void MachineOptimizationRemarkEmitterPass::getAnalysisUsage( AnalysisUsage &AU) const { - LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(AU); + AU.addRequired(); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -85,6 +85,6 @@ INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, false, true) -INITIALIZE_PASS_DEPENDENCY(LazyMachineBFIPass) +INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass) INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass, ORE_NAME, ore_name, false, true)