mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
[SCEV] Refactor out isHighCostExpansion. NFCI.
Summary: Move isHighCostExpansion from IndVarSimplify to SCEVExpander. This exposed function will be used in a subsequent change. Reviewers: bogner, atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8995 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234844 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
41ed49389b
commit
dee1e82714
@ -116,6 +116,13 @@ namespace llvm {
|
||||
ChainedPhis.clear();
|
||||
}
|
||||
|
||||
/// isHighCostExpansion - Return true for expressions that may incur
|
||||
/// non-trivial cost to evaluate at runtime.
|
||||
bool isHighCostExpansion(const SCEV *Expr, Loop *L) {
|
||||
SmallPtrSet<const SCEV *, 8> Processed;
|
||||
return isHighCostExpansionHelper(Expr, L, Processed);
|
||||
}
|
||||
|
||||
/// getOrInsertCanonicalInductionVariable - This method returns the
|
||||
/// canonical induction variable of the specified type for the specified
|
||||
/// loop (inserting one if there is none). A canonical induction variable
|
||||
@ -192,6 +199,11 @@ namespace llvm {
|
||||
private:
|
||||
LLVMContext &getContext() const { return SE.getContext(); }
|
||||
|
||||
/// isHighCostExpansionHelper - Recursive helper function for
|
||||
/// isHighCostExpansion.
|
||||
bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
|
||||
SmallPtrSetImpl<const SCEV *> &Processed);
|
||||
|
||||
/// InsertBinop - Insert the specified binary operator, doing a small amount
|
||||
/// of work to avoid inserting an obviously redundant operation.
|
||||
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@ -1804,6 +1805,61 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
return NumElim;
|
||||
}
|
||||
|
||||
bool SCEVExpander::isHighCostExpansionHelper(
|
||||
const SCEV *S, Loop *L, SmallPtrSetImpl<const SCEV *> &Processed) {
|
||||
if (!Processed.insert(S).second)
|
||||
return false;
|
||||
|
||||
// If the backedge-taken count is a UDiv, it's very likely a UDiv that
|
||||
// ScalarEvolution's HowFarToZero or HowManyLessThans produced to compute a
|
||||
// precise expression, rather than a UDiv from the user's code. If we can't
|
||||
// find a UDiv in the code with some simple searching, assume the former and
|
||||
// forego rewriting the loop.
|
||||
if (isa<SCEVUDivExpr>(S)) {
|
||||
BasicBlock *ExitingBB = L->getExitingBlock();
|
||||
if (!ExitingBB)
|
||||
return true;
|
||||
|
||||
BranchInst *ExitingBI = dyn_cast<BranchInst>(ExitingBB->getTerminator());
|
||||
if (!ExitingBI || !ExitingBI->isConditional())
|
||||
return true;
|
||||
|
||||
ICmpInst *OrigCond = dyn_cast<ICmpInst>(ExitingBI->getCondition());
|
||||
if (!OrigCond)
|
||||
return true;
|
||||
|
||||
const SCEV *RHS = SE.getSCEV(OrigCond->getOperand(1));
|
||||
RHS = SE.getMinusSCEV(RHS, SE.getConstant(RHS->getType(), 1));
|
||||
if (RHS != S) {
|
||||
const SCEV *LHS = SE.getSCEV(OrigCond->getOperand(0));
|
||||
LHS = SE.getMinusSCEV(LHS, SE.getConstant(LHS->getType(), 1));
|
||||
if (LHS != S)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse past add expressions, which commonly occur in the
|
||||
// BackedgeTakenCount. They may already exist in program code, and if not,
|
||||
// they are not too expensive rematerialize.
|
||||
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
||||
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
||||
I != E; ++I) {
|
||||
if (isHighCostExpansionHelper(*I, L, Processed))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// HowManyLessThans uses a Max expression whenever the loop is not guarded by
|
||||
// the exit condition.
|
||||
if (isa<SCEVSMaxExpr>(S) || isa<SCEVUMaxExpr>(S))
|
||||
return true;
|
||||
|
||||
// If we haven't recognized an expensive SCEV pattern, assume it's an
|
||||
// expression produced by program code.
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Search for a SCEV subexpression that is not safe to expand. Any expression
|
||||
// that may expand to a !isSafeToSpeculativelyExecute value is unsafe, namely
|
||||
|
@ -1274,55 +1274,6 @@ void IndVarSimplify::SimplifyAndExtend(Loop *L,
|
||||
// LinearFunctionTestReplace and its kin. Rewrite the loop exit condition.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Check for expressions that ScalarEvolution generates to compute
|
||||
/// BackedgeTakenInfo. If these expressions have not been reduced, then
|
||||
/// expanding them may incur additional cost (albeit in the loop preheader).
|
||||
static bool isHighCostExpansion(const SCEV *S, BranchInst *BI,
|
||||
SmallPtrSetImpl<const SCEV*> &Processed,
|
||||
ScalarEvolution *SE) {
|
||||
if (!Processed.insert(S).second)
|
||||
return false;
|
||||
|
||||
// If the backedge-taken count is a UDiv, it's very likely a UDiv that
|
||||
// ScalarEvolution's HowFarToZero or HowManyLessThans produced to compute a
|
||||
// precise expression, rather than a UDiv from the user's code. If we can't
|
||||
// find a UDiv in the code with some simple searching, assume the former and
|
||||
// forego rewriting the loop.
|
||||
if (isa<SCEVUDivExpr>(S)) {
|
||||
ICmpInst *OrigCond = dyn_cast<ICmpInst>(BI->getCondition());
|
||||
if (!OrigCond) return true;
|
||||
const SCEV *R = SE->getSCEV(OrigCond->getOperand(1));
|
||||
R = SE->getMinusSCEV(R, SE->getConstant(R->getType(), 1));
|
||||
if (R != S) {
|
||||
const SCEV *L = SE->getSCEV(OrigCond->getOperand(0));
|
||||
L = SE->getMinusSCEV(L, SE->getConstant(L->getType(), 1));
|
||||
if (L != S)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse past add expressions, which commonly occur in the
|
||||
// BackedgeTakenCount. They may already exist in program code, and if not,
|
||||
// they are not too expensive rematerialize.
|
||||
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
||||
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
||||
I != E; ++I) {
|
||||
if (isHighCostExpansion(*I, BI, Processed, SE))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// HowManyLessThans uses a Max expression whenever the loop is not guarded by
|
||||
// the exit condition.
|
||||
if (isa<SCEVSMaxExpr>(S) || isa<SCEVUMaxExpr>(S))
|
||||
return true;
|
||||
|
||||
// If we haven't recognized an expensive SCEV pattern, assume it's an
|
||||
// expression produced by program code.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// canExpandBackedgeTakenCount - Return true if this loop's backedge taken
|
||||
/// count expression can be safely and cheaply expanded into an instruction
|
||||
/// sequence that can be used by LinearFunctionTestReplace.
|
||||
@ -1336,7 +1287,8 @@ static bool isHighCostExpansion(const SCEV *S, BranchInst *BI,
|
||||
/// used by ABI constrained operation, as opposed to inttoptr/ptrtoint).
|
||||
/// However, we don't yet have a strong motivation for converting loop tests
|
||||
/// into inequality tests.
|
||||
static bool canExpandBackedgeTakenCount(Loop *L, ScalarEvolution *SE) {
|
||||
static bool canExpandBackedgeTakenCount(Loop *L, ScalarEvolution *SE,
|
||||
SCEVExpander &Rewriter) {
|
||||
const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount) ||
|
||||
BackedgeTakenCount->isZero())
|
||||
@ -1346,12 +1298,10 @@ static bool canExpandBackedgeTakenCount(Loop *L, ScalarEvolution *SE) {
|
||||
return false;
|
||||
|
||||
// Can't rewrite non-branch yet.
|
||||
BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
|
||||
if (!BI)
|
||||
if (!isa<BranchInst>(L->getExitingBlock()->getTerminator()))
|
||||
return false;
|
||||
|
||||
SmallPtrSet<const SCEV*, 8> Processed;
|
||||
if (isHighCostExpansion(BackedgeTakenCount, BI, Processed, SE))
|
||||
if (Rewriter.isHighCostExpansion(BackedgeTakenCount, L))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -1691,7 +1641,7 @@ LinearFunctionTestReplace(Loop *L,
|
||||
const SCEV *BackedgeTakenCount,
|
||||
PHINode *IndVar,
|
||||
SCEVExpander &Rewriter) {
|
||||
assert(canExpandBackedgeTakenCount(L, SE) && "precondition");
|
||||
assert(canExpandBackedgeTakenCount(L, SE, Rewriter) && "precondition");
|
||||
|
||||
// Initialize CmpIndVar and IVCount to their preincremented values.
|
||||
Value *CmpIndVar = IndVar;
|
||||
@ -1936,7 +1886,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
|
||||
// If we have a trip count expression, rewrite the loop's exit condition
|
||||
// using it. We can currently only handle loops with a single exit.
|
||||
if (canExpandBackedgeTakenCount(L, SE) && needsLFTR(L, DT)) {
|
||||
if (canExpandBackedgeTakenCount(L, SE, Rewriter) && needsLFTR(L, DT)) {
|
||||
PHINode *IndVar = FindLoopCounter(L, BackedgeTakenCount, SE, DT);
|
||||
if (IndVar) {
|
||||
// Check preconditions for proper SCEVExpander operation. SCEV does not
|
||||
|
Loading…
Reference in New Issue
Block a user