Skip to content

Commit da4a68a

Browse files
[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
1 parent 183d83b commit da4a68a

File tree

6 files changed

+327
-16
lines changed

6 files changed

+327
-16
lines changed

llvm/include/llvm/Analysis/BranchProbabilityInfo.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace llvm {
2828
class LoopInfo;
29+
class TargetLibraryInfo;
2930
class raw_ostream;
3031

3132
/// \brief Analysis providing branch probability information.
@@ -43,8 +44,9 @@ class raw_ostream;
4344
class BranchProbabilityInfo {
4445
public:
4546
BranchProbabilityInfo() {}
46-
BranchProbabilityInfo(const Function &F, const LoopInfo &LI) {
47-
calculate(F, LI);
47+
BranchProbabilityInfo(const Function &F, const LoopInfo &LI,
48+
const TargetLibraryInfo *TLI = nullptr) {
49+
calculate(F, LI, TLI);
4850
}
4951

5052
BranchProbabilityInfo(BranchProbabilityInfo &&Arg)
@@ -116,7 +118,8 @@ class BranchProbabilityInfo {
116118
return IsLikely ? LikelyProb : LikelyProb.getCompl();
117119
}
118120

119-
void calculate(const Function &F, const LoopInfo &LI);
121+
void calculate(const Function &F, const LoopInfo &LI,
122+
const TargetLibraryInfo *TLI = nullptr);
120123

121124
/// Forget analysis results for the given basic block.
122125
void eraseBlock(const BasicBlock *BB);
@@ -171,7 +174,7 @@ class BranchProbabilityInfo {
171174
bool calcColdCallHeuristics(const BasicBlock *BB);
172175
bool calcPointerHeuristics(const BasicBlock *BB);
173176
bool calcLoopBranchHeuristics(const BasicBlock *BB, const LoopInfo &LI);
174-
bool calcZeroHeuristics(const BasicBlock *BB);
177+
bool calcZeroHeuristics(const BasicBlock *BB, const TargetLibraryInfo *TLI);
175178
bool calcFloatingPointHeuristics(const BasicBlock *BB);
176179
bool calcInvokeHeuristics(const BasicBlock *BB);
177180
};

llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace llvm {
2424
class AnalysisUsage;
2525
class Function;
2626
class LoopInfo;
27+
class TargetLibraryInfo;
2728

2829
/// \brief This is an alternative analysis pass to
2930
/// BranchProbabilityInfoWrapperPass. The difference is that with this pass the
@@ -55,14 +56,15 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
5556
/// analysis without paying for the overhead if BPI doesn't end up being used.
5657
class LazyBranchProbabilityInfo {
5758
public:
58-
LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI)
59-
: Calculated(false), F(F), LI(LI) {}
59+
LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI,
60+
const TargetLibraryInfo *TLI)
61+
: Calculated(false), F(F), LI(LI), TLI(TLI) {}
6062

6163
/// Retrieve the BPI with the branch probabilities computed.
6264
BranchProbabilityInfo &getCalculated() {
6365
if (!Calculated) {
6466
assert(F && LI && "call setAnalysis");
65-
BPI.calculate(*F, *LI);
67+
BPI.calculate(*F, *LI, TLI);
6668
Calculated = true;
6769
}
6870
return BPI;
@@ -77,6 +79,7 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
7779
bool Calculated;
7880
const Function *F;
7981
const LoopInfo *LI;
82+
const TargetLibraryInfo *TLI;
8083
};
8184

8285
std::unique_ptr<LazyBranchProbabilityInfo> LBPI;

llvm/lib/Analysis/BranchProbabilityInfo.cpp

+41-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Analysis/BranchProbabilityInfo.h"
1515
#include "llvm/ADT/PostOrderIterator.h"
1616
#include "llvm/Analysis/LoopInfo.h"
17+
#include "llvm/Analysis/TargetLibraryInfo.h"
1718
#include "llvm/IR/CFG.h"
1819
#include "llvm/IR/Constants.h"
1920
#include "llvm/IR/Function.h"
@@ -30,6 +31,7 @@ using namespace llvm;
3031
INITIALIZE_PASS_BEGIN(BranchProbabilityInfoWrapperPass, "branch-prob",
3132
"Branch Probability Analysis", false, true)
3233
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
34+
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
3335
INITIALIZE_PASS_END(BranchProbabilityInfoWrapperPass, "branch-prob",
3436
"Branch Probability Analysis", false, true)
3537

@@ -457,7 +459,8 @@ bool BranchProbabilityInfo::calcLoopBranchHeuristics(const BasicBlock *BB,
457459
return true;
458460
}
459461

460-
bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB) {
462+
bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
463+
const TargetLibraryInfo *TLI) {
461464
const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
462465
if (!BI || !BI->isConditional())
463466
return false;
@@ -480,8 +483,37 @@ bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB) {
480483
if (AndRHS->getUniqueInteger().isPowerOf2())
481484
return false;
482485

486+
// Check if the LHS is the return value of a library function
487+
LibFunc Func = NumLibFuncs;
488+
if (TLI)
489+
if (CallInst *Call = dyn_cast<CallInst>(CI->getOperand(0)))
490+
if (Function *CalledFn = Call->getCalledFunction())
491+
TLI->getLibFunc(*CalledFn, Func);
492+
483493
bool isProb;
484-
if (CV->isZero()) {
494+
if (Func == LibFunc_strcasecmp ||
495+
Func == LibFunc_strcmp ||
496+
Func == LibFunc_strncasecmp ||
497+
Func == LibFunc_strncmp ||
498+
Func == LibFunc_memcmp) {
499+
// strcmp and similar functions return zero, negative, or positive, if the
500+
// first string is equal, less, or greater than the second. We consider it
501+
// likely that the strings are not equal, so a comparison with zero is
502+
// probably false, but also a comparison with any other number is also
503+
// probably false given that what exactly is returned for nonzero values is
504+
// not specified. Any kind of comparison other than equality we know
505+
// nothing about.
506+
switch (CI->getPredicate()) {
507+
case CmpInst::ICMP_EQ:
508+
isProb = false;
509+
break;
510+
case CmpInst::ICMP_NE:
511+
isProb = true;
512+
break;
513+
default:
514+
return false;
515+
}
516+
} else if (CV->isZero()) {
485517
switch (CI->getPredicate()) {
486518
case CmpInst::ICMP_EQ:
487519
// X == 0 -> Unlikely
@@ -707,7 +739,8 @@ void BranchProbabilityInfo::eraseBlock(const BasicBlock *BB) {
707739
}
708740
}
709741

710-
void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI) {
742+
void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI,
743+
const TargetLibraryInfo *TLI) {
711744
DEBUG(dbgs() << "---- Branch Probability Info : " << F.getName()
712745
<< " ----\n\n");
713746
LastF = &F; // Store the last function we ran on for printing.
@@ -733,7 +766,7 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI) {
733766
continue;
734767
if (calcPointerHeuristics(BB))
735768
continue;
736-
if (calcZeroHeuristics(BB))
769+
if (calcZeroHeuristics(BB, TLI))
737770
continue;
738771
if (calcFloatingPointHeuristics(BB))
739772
continue;
@@ -747,12 +780,14 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI) {
747780
void BranchProbabilityInfoWrapperPass::getAnalysisUsage(
748781
AnalysisUsage &AU) const {
749782
AU.addRequired<LoopInfoWrapperPass>();
783+
AU.addRequired<TargetLibraryInfoWrapperPass>();
750784
AU.setPreservesAll();
751785
}
752786

753787
bool BranchProbabilityInfoWrapperPass::runOnFunction(Function &F) {
754788
const LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
755-
BPI.calculate(F, LI);
789+
const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
790+
BPI.calculate(F, LI, &TLI);
756791
return false;
757792
}
758793

@@ -767,7 +802,7 @@ AnalysisKey BranchProbabilityAnalysis::Key;
767802
BranchProbabilityInfo
768803
BranchProbabilityAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
769804
BranchProbabilityInfo BPI;
770-
BPI.calculate(F, AM.getResult<LoopAnalysis>(F));
805+
BPI.calculate(F, AM.getResult<LoopAnalysis>(F), &AM.getResult<TargetLibraryAnalysis>(F));
771806
return BPI;
772807
}
773808

llvm/lib/Analysis/LazyBranchProbabilityInfo.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/Analysis/LazyBranchProbabilityInfo.h"
1818
#include "llvm/Analysis/LoopInfo.h"
19+
#include "llvm/Analysis/TargetLibraryInfo.h"
1920

2021
using namespace llvm;
2122

@@ -24,6 +25,7 @@ using namespace llvm;
2425
INITIALIZE_PASS_BEGIN(LazyBranchProbabilityInfoPass, DEBUG_TYPE,
2526
"Lazy Branch Probability Analysis", true, true)
2627
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
28+
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
2729
INITIALIZE_PASS_END(LazyBranchProbabilityInfoPass, DEBUG_TYPE,
2830
"Lazy Branch Probability Analysis", true, true)
2931

@@ -41,23 +43,27 @@ void LazyBranchProbabilityInfoPass::print(raw_ostream &OS,
4143

4244
void LazyBranchProbabilityInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
4345
AU.addRequired<LoopInfoWrapperPass>();
46+
AU.addRequired<TargetLibraryInfoWrapperPass>();
4447
AU.setPreservesAll();
4548
}
4649

4750
void LazyBranchProbabilityInfoPass::releaseMemory() { LBPI.reset(); }
4851

4952
bool LazyBranchProbabilityInfoPass::runOnFunction(Function &F) {
5053
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
51-
LBPI = llvm::make_unique<LazyBranchProbabilityInfo>(&F, &LI);
54+
TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
55+
LBPI = llvm::make_unique<LazyBranchProbabilityInfo>(&F, &LI, &TLI);
5256
return false;
5357
}
5458

5559
void LazyBranchProbabilityInfoPass::getLazyBPIAnalysisUsage(AnalysisUsage &AU) {
5660
AU.addRequired<LazyBranchProbabilityInfoPass>();
5761
AU.addRequired<LoopInfoWrapperPass>();
62+
AU.addRequired<TargetLibraryInfoWrapperPass>();
5863
}
5964

6065
void llvm::initializeLazyBPIPassPass(PassRegistry &Registry) {
6166
INITIALIZE_PASS_DEPENDENCY(LazyBranchProbabilityInfoPass);
6267
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
68+
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass);
6369
}

llvm/lib/Transforms/Scalar/JumpThreading.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ bool JumpThreading::runOnFunction(Function &F) {
132132
bool HasProfileData = F.getEntryCount().hasValue();
133133
if (HasProfileData) {
134134
LoopInfo LI{DominatorTree(F)};
135-
BPI.reset(new BranchProbabilityInfo(F, LI));
135+
BPI.reset(new BranchProbabilityInfo(F, LI, TLI));
136136
BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));
137137
}
138138

@@ -152,7 +152,7 @@ PreservedAnalyses JumpThreadingPass::run(Function &F,
152152
bool HasProfileData = F.getEntryCount().hasValue();
153153
if (HasProfileData) {
154154
LoopInfo LI{DominatorTree(F)};
155-
BPI.reset(new BranchProbabilityInfo(F, LI));
155+
BPI.reset(new BranchProbabilityInfo(F, LI, &TLI));
156156
BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));
157157
}
158158

0 commit comments

Comments
 (0)