#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 {
/// 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<LazyMachineBlockFrequencyInfoPass>().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<MachineFunction, MachineBranchProbabilityInfo,
- MachineLoopInfo, MachineBlockFrequencyInfo>
- LMBFI;
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineBlockFrequencyInfo> OwnedMBFI;
+
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineLoopInfo> OwnedMLI;
+
+ /// If generated on the fly this own the instance.
+ mutable std::unique_ptr<MachineDominatorTree> 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;
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
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<MachineBranchProbabilityInfo>();
- AU.addRequired<MachineLoopInfo>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
void LazyMachineBlockFrequencyInfoPass::releaseMemory() {
- LMBFI.releaseMemory();
+ OwnedMBFI.reset();
+ OwnedMLI.reset();
+ OwnedMDT.reset();
}
-bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction(
- MachineFunction &MF) {
- auto &BPIPass = getAnalysis<MachineBranchProbabilityInfo>();
- auto &LI = getAnalysis<MachineLoopInfo>();
- LMBFI.setAnalysis(&MF, &BPIPass, &LI);
- return false;
-}
+MachineBlockFrequencyInfo &
+LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const {
+ auto *MBFI = getAnalysisIfAvailable<MachineBlockFrequencyInfo>();
+ if (MBFI) {
+ DEBUG(dbgs() << "MachineBlockFrequencyInfo is available\n");
+ return *MBFI;
+ }
-void LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(
- AnalysisUsage &AU) {
- AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
- AU.addRequired<MachineBranchProbabilityInfo>();
- AU.addRequired<MachineLoopInfo>();
+ auto &MBPI = getAnalysis<MachineBranchProbabilityInfo>();
+ auto *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
+ auto *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
+ 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<MachineDominatorTree>();
+ OwnedMDT->getBase().recalculate(*MF);
+ MDT = OwnedMDT.get();
+ }
+
+ // Generate LoopInfo from it.
+ OwnedMLI = make_unique<MachineLoopInfo>();
+ OwnedMLI->getBase().analyze(MDT->getBase());
+ MLI = OwnedMLI.get();
+ }
+
+ OwnedMBFI = make_unique<MachineBlockFrequencyInfo>();
+ OwnedMBFI->calculate(*MF, MBPI, *MLI);
+ return *OwnedMBFI.get();
}
-void llvm::initializeLazyMachineBFIPassPass(PassRegistry &Registry) {
- INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass);
- INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo);
- INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo);
+bool LazyMachineBlockFrequencyInfoPass::runOnMachineFunction(
+ MachineFunction &F) {
+ MF = &F;
+ return false;
}
void MachineOptimizationRemarkEmitterPass::getAnalysisUsage(
AnalysisUsage &AU) const {
- LazyMachineBlockFrequencyInfoPass::getLazyMachineBFIAnalysisUsage(AU);
+ AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
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)