1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00
llvm-mirror/include/llvm/Analysis/LazyBranchProbabilityInfo.h
John Brawn 9f05fb5e02 [BPI] Don't assume that strcmp returning >0 is more likely than <0
The zero heuristic assumes that integers are more likely positive than negative,
but this also has the effect of assuming that strcmp return values are more
likely positive than negative. Given that for nonzero strcmp return values it's
the ordering of arguments that determines the sign of the result there's no
reason to assume that's true.

Fix this by inspecting the LHS of the compare and using TargetLibraryInfo to
decide if it's strcmp-like, and if so only assume that nonzero is more likely
than zero i.e. strings are more often different than the same. This causes a
slight code generation change in the spec2006 benchmark 403.gcc, but with no
noticeable performance impact. The intent of this patch is to allow better
optimisation of dhrystone on Cortex-M cpus, but currently it won't as there are
also some changes that need to be made to if-conversion.

Differential Revision: https://reviews.llvm.org/D33934

llvm-svn: 304970
2017-06-08 09:44:40 +00:00

125 lines
4.2 KiB
C++

//===- LazyBranchProbabilityInfo.h - Lazy Branch Probability ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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;
class TargetLibraryInfo;
/// \brief 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.
///
/// 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:
LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI,
const TargetLibraryInfo *TLI)
: Calculated(false), F(F), LI(LI), TLI(TLI) {}
/// Retrieve the BPI with the branch probabilities computed.
BranchProbabilityInfo &getCalculated() {
if (!Calculated) {
assert(F && LI && "call setAnalysis");
BPI.calculate(*F, *LI, TLI);
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;
const TargetLibraryInfo *TLI;
};
std::unique_ptr<LazyBranchProbabilityInfo> LBPI;
public:
static char ID;
LazyBranchProbabilityInfoPass();
/// \brief Compute and return the branch probabilities.
BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); }
/// \brief Compute and return the branch probabilities.
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;
};
/// \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 <typename PassT> struct BPIPassTrait {
static PassT &getBPI(PassT *P) { return *P; }
};
template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> {
static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) {
return P->getBPI();
}
};
}
#endif