mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-26 07:24:25 +00:00
Teach IRCE to look at branch weights when recognizing range checks
Splitting a loop to make range checks redundant is profitable only if the range check "never" fails. Make this fact a part of recognizing a range check -- a branch is a range check only if it is expected to pass (via branch_weights metadata). Differential Revision: http://reviews.llvm.org/D7192 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227249 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -43,6 +43,7 @@
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||
#include "llvm/Analysis/InstructionSimplify.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
@ -169,7 +170,8 @@ public:
|
||||
/// Create an inductive range check out of BI if possible, else return
|
||||
/// nullptr.
|
||||
static InductiveRangeCheck *create(AllocatorTy &Alloc, BranchInst *BI,
|
||||
Loop *L, ScalarEvolution &SE);
|
||||
Loop *L, ScalarEvolution &SE,
|
||||
BranchProbabilityInfo &BPI);
|
||||
};
|
||||
|
||||
class InductiveRangeCheckElimination : public LoopPass {
|
||||
@ -187,6 +189,7 @@ public:
|
||||
AU.addRequiredID(LoopSimplifyID);
|
||||
AU.addRequiredID(LCSSAID);
|
||||
AU.addRequired<ScalarEvolution>();
|
||||
AU.addRequired<BranchProbabilityInfo>();
|
||||
}
|
||||
|
||||
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
|
||||
@ -354,13 +357,20 @@ static bool SplitRangeCheckCondition(Loop *L, ScalarEvolution &SE,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
InductiveRangeCheck *
|
||||
InductiveRangeCheck::create(InductiveRangeCheck::AllocatorTy &A, BranchInst *BI,
|
||||
Loop *L, ScalarEvolution &SE) {
|
||||
Loop *L, ScalarEvolution &SE,
|
||||
BranchProbabilityInfo &BPI) {
|
||||
|
||||
if (BI->isUnconditional() || BI->getParent() == L->getLoopLatch())
|
||||
return nullptr;
|
||||
|
||||
BranchProbability LikelyTaken(15, 16);
|
||||
|
||||
if (BPI.getEdgeProbability(BI->getParent(), (unsigned) 0) < LikelyTaken)
|
||||
return nullptr;
|
||||
|
||||
Value *Length = nullptr;
|
||||
const SCEV *IndexSCEV = nullptr;
|
||||
|
||||
@ -1175,11 +1185,12 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
InductiveRangeCheck::AllocatorTy IRCAlloc;
|
||||
SmallVector<InductiveRangeCheck *, 16> RangeChecks;
|
||||
ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
|
||||
BranchProbabilityInfo &BPI = getAnalysis<BranchProbabilityInfo>();
|
||||
|
||||
for (auto BBI : L->getBlocks())
|
||||
if (BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
|
||||
if (InductiveRangeCheck *IRC =
|
||||
InductiveRangeCheck::create(IRCAlloc, TBI, L, SE))
|
||||
InductiveRangeCheck::create(IRCAlloc, TBI, L, SE, BPI))
|
||||
RangeChecks.push_back(IRC);
|
||||
|
||||
if (RangeChecks.empty())
|
||||
|
Reference in New Issue
Block a user