2016-07-29 01:31:12 +02:00
|
|
|
//===- LazyBranchProbabilityInfo.h - Lazy Branch Probability ----*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-07-29 01:31:12 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This is an alternative analysis pass to BranchProbabilityInfoWrapperPass.
|
|
|
|
// The difference is that with this pass the branch probabilities are not
|
|
|
|
// computed when the analysis pass is executed but rather when the BPI results
|
|
|
|
// is explicitly requested by the analysis client.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H
|
|
|
|
#define LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H
|
|
|
|
|
|
|
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
|
|
|
#include "llvm/Pass.h"
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
class AnalysisUsage;
|
|
|
|
class Function;
|
|
|
|
class LoopInfo;
|
2017-06-08 11:44:40 +02:00
|
|
|
class TargetLibraryInfo;
|
2016-07-29 01:31:12 +02:00
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// This is an alternative analysis pass to
|
2016-07-29 01:31:12 +02:00
|
|
|
/// BranchProbabilityInfoWrapperPass. The difference is that with this pass the
|
|
|
|
/// branch probabilities are not computed when the analysis pass is executed but
|
|
|
|
/// rather when the BPI 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(LazyBPIPass)
|
|
|
|
///
|
|
|
|
/// 2. Similarly, getAnalysisUsage should call:
|
|
|
|
///
|
|
|
|
/// LazyBranchProbabilityInfoPass::getLazyBPIAnalysisUsage(AU)
|
|
|
|
///
|
|
|
|
/// 3. The computed BPI should be requested with
|
|
|
|
/// getAnalysis<LazyBranchProbabilityInfoPass>().getBPI() before LoopInfo
|
|
|
|
/// 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 LazyBranchProbabilityInfoPass : public FunctionPass {
|
|
|
|
|
|
|
|
/// Wraps a BPI to allow lazy computation of the branch probabilities.
|
|
|
|
///
|
|
|
|
/// A pass that only conditionally uses BPI can uncondtionally require the
|
|
|
|
/// analysis without paying for the overhead if BPI doesn't end up being used.
|
|
|
|
class LazyBranchProbabilityInfo {
|
|
|
|
public:
|
2017-06-08 11:44:40 +02:00
|
|
|
LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI,
|
|
|
|
const TargetLibraryInfo *TLI)
|
|
|
|
: Calculated(false), F(F), LI(LI), TLI(TLI) {}
|
2016-07-29 01:31:12 +02:00
|
|
|
|
|
|
|
/// Retrieve the BPI with the branch probabilities computed.
|
|
|
|
BranchProbabilityInfo &getCalculated() {
|
|
|
|
if (!Calculated) {
|
|
|
|
assert(F && LI && "call setAnalysis");
|
2020-06-18 11:20:55 +02:00
|
|
|
BPI.calculate(*F, *LI, TLI, nullptr, nullptr);
|
2016-07-29 01:31:12 +02:00
|
|
|
Calculated = true;
|
|
|
|
}
|
|
|
|
return BPI;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BranchProbabilityInfo &getCalculated() const {
|
|
|
|
return const_cast<LazyBranchProbabilityInfo *>(this)->getCalculated();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
BranchProbabilityInfo BPI;
|
|
|
|
bool Calculated;
|
|
|
|
const Function *F;
|
|
|
|
const LoopInfo *LI;
|
2017-06-08 11:44:40 +02:00
|
|
|
const TargetLibraryInfo *TLI;
|
2016-07-29 01:31:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
std::unique_ptr<LazyBranchProbabilityInfo> LBPI;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static char ID;
|
|
|
|
|
|
|
|
LazyBranchProbabilityInfoPass();
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Compute and return the branch probabilities.
|
2016-07-29 01:31:12 +02:00
|
|
|
BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); }
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Compute and return the branch probabilities.
|
2016-07-29 01:31:12 +02:00
|
|
|
const BranchProbabilityInfo &getBPI() const { return LBPI->getCalculated(); }
|
|
|
|
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
|
|
|
|
|
|
|
/// Helper for client passes to set up the analysis usage on behalf of this
|
|
|
|
/// pass.
|
|
|
|
static void getLazyBPIAnalysisUsage(AnalysisUsage &AU);
|
|
|
|
|
|
|
|
bool runOnFunction(Function &F) override;
|
|
|
|
void releaseMemory() override;
|
|
|
|
void print(raw_ostream &OS, const Module *M) const override;
|
|
|
|
};
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Helper for client passes to initialize dependent passes for LBPI.
|
2016-07-29 01:31:12 +02:00
|
|
|
void initializeLazyBPIPassPass(PassRegistry &Registry);
|
2017-02-14 18:21:09 +01:00
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// Simple trait class that provides a mapping between BPI passes and the
|
2017-02-14 18:21:09 +01:00
|
|
|
/// corresponding BPInfo.
|
|
|
|
template <typename PassT> struct BPIPassTrait {
|
|
|
|
static PassT &getBPI(PassT *P) { return *P; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> {
|
|
|
|
static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) {
|
|
|
|
return P->getBPI();
|
|
|
|
}
|
|
|
|
};
|
2016-07-29 01:31:12 +02:00
|
|
|
}
|
|
|
|
#endif
|