mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-26 05:25:47 +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:
@@ -116,6 +116,13 @@ namespace llvm {
|
|||||||
ChainedPhis.clear();
|
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
|
/// getOrInsertCanonicalInductionVariable - This method returns the
|
||||||
/// canonical induction variable of the specified type for the specified
|
/// canonical induction variable of the specified type for the specified
|
||||||
/// loop (inserting one if there is none). A canonical induction variable
|
/// loop (inserting one if there is none). A canonical induction variable
|
||||||
@@ -192,6 +199,11 @@ namespace llvm {
|
|||||||
private:
|
private:
|
||||||
LLVMContext &getContext() const { return SE.getContext(); }
|
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
|
/// InsertBinop - Insert the specified binary operator, doing a small amount
|
||||||
/// of work to avoid inserting an obviously redundant operation.
|
/// of work to avoid inserting an obviously redundant operation.
|
||||||
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
|
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/IntrinsicInst.h"
|
#include "llvm/IR/IntrinsicInst.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
@@ -1804,6 +1805,61 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
|||||||
return NumElim;
|
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 {
|
namespace {
|
||||||
// Search for a SCEV subexpression that is not safe to expand. Any expression
|
// Search for a SCEV subexpression that is not safe to expand. Any expression
|
||||||
// that may expand to a !isSafeToSpeculativelyExecute value is unsafe, namely
|
// 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.
|
// 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
|
/// canExpandBackedgeTakenCount - Return true if this loop's backedge taken
|
||||||
/// count expression can be safely and cheaply expanded into an instruction
|
/// count expression can be safely and cheaply expanded into an instruction
|
||||||
/// sequence that can be used by LinearFunctionTestReplace.
|
/// 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).
|
/// used by ABI constrained operation, as opposed to inttoptr/ptrtoint).
|
||||||
/// However, we don't yet have a strong motivation for converting loop tests
|
/// However, we don't yet have a strong motivation for converting loop tests
|
||||||
/// into inequality 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);
|
const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount) ||
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount) ||
|
||||||
BackedgeTakenCount->isZero())
|
BackedgeTakenCount->isZero())
|
||||||
@@ -1346,12 +1298,10 @@ static bool canExpandBackedgeTakenCount(Loop *L, ScalarEvolution *SE) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can't rewrite non-branch yet.
|
// Can't rewrite non-branch yet.
|
||||||
BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
|
if (!isa<BranchInst>(L->getExitingBlock()->getTerminator()))
|
||||||
if (!BI)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SmallPtrSet<const SCEV*, 8> Processed;
|
if (Rewriter.isHighCostExpansion(BackedgeTakenCount, L))
|
||||||
if (isHighCostExpansion(BackedgeTakenCount, BI, Processed, SE))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1691,7 +1641,7 @@ LinearFunctionTestReplace(Loop *L,
|
|||||||
const SCEV *BackedgeTakenCount,
|
const SCEV *BackedgeTakenCount,
|
||||||
PHINode *IndVar,
|
PHINode *IndVar,
|
||||||
SCEVExpander &Rewriter) {
|
SCEVExpander &Rewriter) {
|
||||||
assert(canExpandBackedgeTakenCount(L, SE) && "precondition");
|
assert(canExpandBackedgeTakenCount(L, SE, Rewriter) && "precondition");
|
||||||
|
|
||||||
// Initialize CmpIndVar and IVCount to their preincremented values.
|
// Initialize CmpIndVar and IVCount to their preincremented values.
|
||||||
Value *CmpIndVar = IndVar;
|
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
|
// 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.
|
// 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);
|
PHINode *IndVar = FindLoopCounter(L, BackedgeTakenCount, SE, DT);
|
||||||
if (IndVar) {
|
if (IndVar) {
|
||||||
// Check preconditions for proper SCEVExpander operation. SCEV does not
|
// Check preconditions for proper SCEVExpander operation. SCEV does not
|
||||||
|
Reference in New Issue
Block a user