aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-08-22 19:00:43 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-11-13 20:39:49 +0000
commitfe6060f10f634930ff71b7c50291ddc610da2475 (patch)
tree1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parentb61bce17f346d79cecfd8f195a64b10f77be43b1 (diff)
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp392
1 files changed, 225 insertions, 167 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 6dbfb0b61fea..3978e1e29825 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -29,6 +29,12 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
+#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
+#define SCEV_DEBUG_WITH_TYPE(TYPE, X) DEBUG_WITH_TYPE(TYPE, X)
+#else
+#define SCEV_DEBUG_WITH_TYPE(TYPE, X)
+#endif
+
using namespace llvm;
cl::opt<unsigned> llvm::SCEVCheapExpansionBudget(
@@ -55,7 +61,7 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// not allowed to move it.
BasicBlock::iterator BIP = Builder.GetInsertPoint();
- Instruction *Ret = nullptr;
+ Value *Ret = nullptr;
// Check to see if there is already a cast!
for (User *U : V->users()) {
@@ -76,20 +82,23 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty,
// Create a new cast.
if (!Ret) {
- Ret = CastInst::Create(Op, V, Ty, V->getName(), &*IP);
- rememberInstruction(Ret);
+ SCEVInsertPointGuard Guard(Builder, this);
+ Builder.SetInsertPoint(&*IP);
+ Ret = Builder.CreateCast(Op, V, Ty, V->getName());
}
// We assert at the end of the function since IP might point to an
// instruction with different dominance properties than a cast
// (an invoke for example) and not dominate BIP (but the cast does).
- assert(SE.DT.dominates(Ret, &*BIP));
+ assert(!isa<Instruction>(Ret) ||
+ SE.DT.dominates(cast<Instruction>(Ret), &*BIP));
return Ret;
}
BasicBlock::iterator
-SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) {
+SCEVExpander::findInsertPointAfter(Instruction *I,
+ Instruction *MustDominate) const {
BasicBlock::iterator IP = ++I->getIterator();
if (auto *II = dyn_cast<InvokeInst>(I))
IP = II->getNormalDest()->begin();
@@ -114,6 +123,34 @@ SCEVExpander::findInsertPointAfter(Instruction *I, Instruction *MustDominate) {
return IP;
}
+BasicBlock::iterator
+SCEVExpander::GetOptimalInsertionPointForCastOf(Value *V) const {
+ // Cast the argument at the beginning of the entry block, after
+ // any bitcasts of other arguments.
+ if (Argument *A = dyn_cast<Argument>(V)) {
+ BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin();
+ while ((isa<BitCastInst>(IP) &&
+ isa<Argument>(cast<BitCastInst>(IP)->getOperand(0)) &&
+ cast<BitCastInst>(IP)->getOperand(0) != A) ||
+ isa<DbgInfoIntrinsic>(IP))
+ ++IP;
+ return IP;
+ }
+
+ // Cast the instruction immediately after the instruction.
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return findInsertPointAfter(I, &*Builder.GetInsertPoint());
+
+ // Otherwise, this must be some kind of a constant,
+ // so let's plop this cast into the function's entry block.
+ assert(isa<Constant>(V) &&
+ "Expected the cast argument to be a global/constant");
+ return Builder.GetInsertBlock()
+ ->getParent()
+ ->getEntryBlock()
+ .getFirstInsertionPt();
+}
+
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
/// which must be possible with a noop cast, doing what we can to share
/// the casts.
@@ -172,22 +209,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
if (Constant *C = dyn_cast<Constant>(V))
return ConstantExpr::getCast(Op, C, Ty);
- // Cast the argument at the beginning of the entry block, after
- // any bitcasts of other arguments.
- if (Argument *A = dyn_cast<Argument>(V)) {
- BasicBlock::iterator IP = A->getParent()->getEntryBlock().begin();
- while ((isa<BitCastInst>(IP) &&
- isa<Argument>(cast<BitCastInst>(IP)->getOperand(0)) &&
- cast<BitCastInst>(IP)->getOperand(0) != A) ||
- isa<DbgInfoIntrinsic>(IP))
- ++IP;
- return ReuseOrCreateCast(A, Ty, Op, IP);
- }
-
- // Cast the instruction immediately after the instruction.
- Instruction *I = cast<Instruction>(V);
- BasicBlock::iterator IP = findInsertPointAfter(I, &*Builder.GetInsertPoint());
- return ReuseOrCreateCast(I, Ty, Op, IP);
+ // Try to reuse existing cast, or insert one.
+ return ReuseOrCreateCast(V, Ty, Op, GetOptimalInsertionPointForCastOf(V));
}
/// InsertBinop - Insert the specified binary operator, doing a small amount
@@ -430,8 +453,6 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
PointerType *PTy,
Type *Ty,
Value *V) {
- Type *OriginalElTy = PTy->getElementType();
- Type *ElTy = OriginalElTy;
SmallVector<Value *, 4> GepIndices;
SmallVector<const SCEV *, 8> Ops(op_begin, op_end);
bool AnyNonZeroIndices = false;
@@ -442,93 +463,97 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
Type *IntIdxTy = DL.getIndexType(PTy);
- // Descend down the pointer's type and attempt to convert the other
- // operands into GEP indices, at each level. The first index in a GEP
- // indexes into the array implied by the pointer operand; the rest of
- // the indices index into the element or field type selected by the
- // preceding index.
- for (;;) {
- // If the scale size is not 0, attempt to factor out a scale for
- // array indexing.
- SmallVector<const SCEV *, 8> ScaledOps;
- if (ElTy->isSized()) {
- const SCEV *ElSize = SE.getSizeOfExpr(IntIdxTy, ElTy);
- if (!ElSize->isZero()) {
- SmallVector<const SCEV *, 8> NewOps;
- for (const SCEV *Op : Ops) {
- const SCEV *Remainder = SE.getConstant(Ty, 0);
- if (FactorOutConstant(Op, Remainder, ElSize, SE, DL)) {
- // Op now has ElSize factored out.
- ScaledOps.push_back(Op);
- if (!Remainder->isZero())
- NewOps.push_back(Remainder);
- AnyNonZeroIndices = true;
- } else {
- // The operand was not divisible, so add it to the list of operands
- // we'll scan next iteration.
- NewOps.push_back(Op);
+ // For opaque pointers, always generate i8 GEP.
+ if (!PTy->isOpaque()) {
+ // Descend down the pointer's type and attempt to convert the other
+ // operands into GEP indices, at each level. The first index in a GEP
+ // indexes into the array implied by the pointer operand; the rest of
+ // the indices index into the element or field type selected by the
+ // preceding index.
+ Type *ElTy = PTy->getElementType();
+ for (;;) {
+ // If the scale size is not 0, attempt to factor out a scale for
+ // array indexing.
+ SmallVector<const SCEV *, 8> ScaledOps;
+ if (ElTy->isSized()) {
+ const SCEV *ElSize = SE.getSizeOfExpr(IntIdxTy, ElTy);
+ if (!ElSize->isZero()) {
+ SmallVector<const SCEV *, 8> NewOps;
+ for (const SCEV *Op : Ops) {
+ const SCEV *Remainder = SE.getConstant(Ty, 0);
+ if (FactorOutConstant(Op, Remainder, ElSize, SE, DL)) {
+ // Op now has ElSize factored out.
+ ScaledOps.push_back(Op);
+ if (!Remainder->isZero())
+ NewOps.push_back(Remainder);
+ AnyNonZeroIndices = true;
+ } else {
+ // The operand was not divisible, so add it to the list of
+ // operands we'll scan next iteration.
+ NewOps.push_back(Op);
+ }
+ }
+ // If we made any changes, update Ops.
+ if (!ScaledOps.empty()) {
+ Ops = NewOps;
+ SimplifyAddOperands(Ops, Ty, SE);
}
- }
- // If we made any changes, update Ops.
- if (!ScaledOps.empty()) {
- Ops = NewOps;
- SimplifyAddOperands(Ops, Ty, SE);
}
}
- }
- // Record the scaled array index for this level of the type. If
- // we didn't find any operands that could be factored, tentatively
- // assume that element zero was selected (since the zero offset
- // would obviously be folded away).
- Value *Scaled =
- ScaledOps.empty()
- ? Constant::getNullValue(Ty)
- : expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty, false);
- GepIndices.push_back(Scaled);
-
- // Collect struct field index operands.
- while (StructType *STy = dyn_cast<StructType>(ElTy)) {
- bool FoundFieldNo = false;
- // An empty struct has no fields.
- if (STy->getNumElements() == 0) break;
- // Field offsets are known. See if a constant offset falls within any of
- // the struct fields.
- if (Ops.empty())
- break;
- if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[0]))
- if (SE.getTypeSizeInBits(C->getType()) <= 64) {
- const StructLayout &SL = *DL.getStructLayout(STy);
- uint64_t FullOffset = C->getValue()->getZExtValue();
- if (FullOffset < SL.getSizeInBytes()) {
- unsigned ElIdx = SL.getElementContainingOffset(FullOffset);
- GepIndices.push_back(
- ConstantInt::get(Type::getInt32Ty(Ty->getContext()), ElIdx));
- ElTy = STy->getTypeAtIndex(ElIdx);
- Ops[0] =
- SE.getConstant(Ty, FullOffset - SL.getElementOffset(ElIdx));
- AnyNonZeroIndices = true;
- FoundFieldNo = true;
+ // Record the scaled array index for this level of the type. If
+ // we didn't find any operands that could be factored, tentatively
+ // assume that element zero was selected (since the zero offset
+ // would obviously be folded away).
+ Value *Scaled =
+ ScaledOps.empty()
+ ? Constant::getNullValue(Ty)
+ : expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty, false);
+ GepIndices.push_back(Scaled);
+
+ // Collect struct field index operands.
+ while (StructType *STy = dyn_cast<StructType>(ElTy)) {
+ bool FoundFieldNo = false;
+ // An empty struct has no fields.
+ if (STy->getNumElements() == 0) break;
+ // Field offsets are known. See if a constant offset falls within any of
+ // the struct fields.
+ if (Ops.empty())
+ break;
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[0]))
+ if (SE.getTypeSizeInBits(C->getType()) <= 64) {
+ const StructLayout &SL = *DL.getStructLayout(STy);
+ uint64_t FullOffset = C->getValue()->getZExtValue();
+ if (FullOffset < SL.getSizeInBytes()) {
+ unsigned ElIdx = SL.getElementContainingOffset(FullOffset);
+ GepIndices.push_back(
+ ConstantInt::get(Type::getInt32Ty(Ty->getContext()), ElIdx));
+ ElTy = STy->getTypeAtIndex(ElIdx);
+ Ops[0] =
+ SE.getConstant(Ty, FullOffset - SL.getElementOffset(ElIdx));
+ AnyNonZeroIndices = true;
+ FoundFieldNo = true;
+ }
}
+ // If no struct field offsets were found, tentatively assume that
+ // field zero was selected (since the zero offset would obviously
+ // be folded away).
+ if (!FoundFieldNo) {
+ ElTy = STy->getTypeAtIndex(0u);
+ GepIndices.push_back(
+ Constant::getNullValue(Type::getInt32Ty(Ty->getContext())));
}
- // If no struct field offsets were found, tentatively assume that
- // field zero was selected (since the zero offset would obviously
- // be folded away).
- if (!FoundFieldNo) {
- ElTy = STy->getTypeAtIndex(0u);
- GepIndices.push_back(
- Constant::getNullValue(Type::getInt32Ty(Ty->getContext())));
}
- }
- if (ArrayType *ATy = dyn_cast<ArrayType>(ElTy))
- ElTy = ATy->getElementType();
- else
- // FIXME: Handle VectorType.
- // E.g., If ElTy is scalable vector, then ElSize is not a compile-time
- // constant, therefore can not be factored out. The generated IR is less
- // ideal with base 'V' cast to i8* and do ugly getelementptr over that.
- break;
+ if (ArrayType *ATy = dyn_cast<ArrayType>(ElTy))
+ ElTy = ATy->getElementType();
+ else
+ // FIXME: Handle VectorType.
+ // E.g., If ElTy is scalable vector, then ElSize is not a compile-time
+ // constant, therefore can not be factored out. The generated IR is less
+ // ideal with base 'V' cast to i8* and do ugly getelementptr over that.
+ break;
+ }
}
// If none of the operands were convertible to proper GEP indices, cast
@@ -536,8 +561,9 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// better than ptrtoint+arithmetic+inttoptr at least.
if (!AnyNonZeroIndices) {
// Cast the base to i8*.
- V = InsertNoopCastOfTo(V,
- Type::getInt8PtrTy(Ty->getContext(), PTy->getAddressSpace()));
+ if (!PTy->isOpaque())
+ V = InsertNoopCastOfTo(V,
+ Type::getInt8PtrTy(Ty->getContext(), PTy->getAddressSpace()));
assert(!isa<Instruction>(V) ||
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
@@ -613,7 +639,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
Value *Casted = V;
if (V->getType() != PTy)
Casted = InsertNoopCastOfTo(Casted, PTy);
- Value *GEP = Builder.CreateGEP(OriginalElTy, Casted, GepIndices, "scevgep");
+ Value *GEP = Builder.CreateGEP(PTy->getElementType(), Casted, GepIndices,
+ "scevgep");
Ops.push_back(SE.getUnknown(GEP));
}
@@ -929,9 +956,8 @@ bool SCEVExpander::isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV,
// Addrec operands are always loop-invariant, so this can only happen
// if there are instructions which haven't been hoisted.
if (L == IVIncInsertLoop) {
- for (User::op_iterator OI = IncV->op_begin()+1,
- OE = IncV->op_end(); OI != OE; ++OI)
- if (Instruction *OInst = dyn_cast<Instruction>(OI))
+ for (Use &Op : llvm::drop_begin(IncV->operands()))
+ if (Instruction *OInst = dyn_cast<Instruction>(Op))
if (!SE.DT.dominates(OInst, IVIncInsertPos))
return false;
}
@@ -978,10 +1004,10 @@ Instruction *SCEVExpander::getIVIncOperand(Instruction *IncV,
case Instruction::BitCast:
return dyn_cast<Instruction>(IncV->getOperand(0));
case Instruction::GetElementPtr:
- for (auto I = IncV->op_begin() + 1, E = IncV->op_end(); I != E; ++I) {
- if (isa<Constant>(*I))
+ for (Use &U : llvm::drop_begin(IncV->operands())) {
+ if (isa<Constant>(U))
continue;
- if (Instruction *OInst = dyn_cast<Instruction>(*I)) {
+ if (Instruction *OInst = dyn_cast<Instruction>(U)) {
if (!SE.DT.dominates(OInst, InsertPos))
return nullptr;
}
@@ -1121,6 +1147,10 @@ static bool canBeCheaplyTransformed(ScalarEvolution &SE,
const SCEVAddRecExpr *Phi,
const SCEVAddRecExpr *Requested,
bool &InvertStep) {
+ // We can't transform to match a pointer PHI.
+ if (Phi->getType()->isPointerTy())
+ return false;
+
Type *PhiTy = SE.getEffectiveSCEVType(Phi->getType());
Type *RequestedTy = SE.getEffectiveSCEVType(Requested->getType());
@@ -1139,8 +1169,7 @@ static bool canBeCheaplyTransformed(ScalarEvolution &SE,
}
// Check whether inverting will help: {R,+,-1} == R - {0,+,1}.
- if (SE.getAddExpr(Requested->getStart(),
- SE.getNegativeSCEV(Requested)) == Phi) {
+ if (SE.getMinusSCEV(Requested->getStart(), Requested) == Phi) {
InvertStep = true;
return true;
}
@@ -1209,7 +1238,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// We should not look for a incomplete PHI. Getting SCEV for a incomplete
// PHI has no meaning at all.
if (!PN.isComplete()) {
- DEBUG_WITH_TYPE(
+ SCEV_DEBUG_WITH_TYPE(
DebugType, dbgs() << "One incomplete PHI is found: " << PN << "\n");
continue;
}
@@ -1364,9 +1393,10 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// can ensure that IVIncrement dominates the current uses.
PostIncLoops = SavedPostIncLoops;
- // Remember this PHI, even in post-inc mode.
+ // Remember this PHI, even in post-inc mode. LSR SCEV-based salvaging is most
+ // effective when we are able to use an IV inserted here, so record it.
InsertedValues.insert(PN);
-
+ InsertedIVs.push_back(PN);
return PN;
}
@@ -1551,8 +1581,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
// Rewrite an AddRec in terms of the canonical induction variable, if
// its type is more narrow.
if (CanonicalIV &&
- SE.getTypeSizeInBits(CanonicalIV->getType()) >
- SE.getTypeSizeInBits(Ty)) {
+ SE.getTypeSizeInBits(CanonicalIV->getType()) > SE.getTypeSizeInBits(Ty) &&
+ !S->getType()->isPointerTy()) {
SmallVector<const SCEV *, 4> NewOps(S->getNumOperands());
for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i)
NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType());
@@ -1677,7 +1707,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
Value *SCEVExpander::visitPtrToIntExpr(const SCEVPtrToIntExpr *S) {
Value *V =
expandCodeForImpl(S->getOperand(), S->getOperand()->getType(), false);
- return Builder.CreatePtrToInt(V, S->getType());
+ return ReuseOrCreateCast(V, S->getType(), CastInst::PtrToInt,
+ GetOptimalInsertionPointForCastOf(V));
}
Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
@@ -1716,8 +1747,14 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::smax, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "smax");
+ else {
+ Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1739,8 +1776,14 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::umax, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "umax");
+ else {
+ Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1762,8 +1805,14 @@ Value *SCEVExpander::visitSMinExpr(const SCEVSMinExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::smin, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "smin");
+ else {
+ Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1785,8 +1834,14 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
LHS = InsertNoopCastOfTo(LHS, Ty);
}
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
- Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
- Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
+ Value *Sel;
+ if (Ty->isIntegerTy())
+ Sel = Builder.CreateIntrinsic(Intrinsic::umin, {Ty}, {LHS, RHS},
+ /*FMFSource=*/nullptr, "umin");
+ else {
+ Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
+ Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
+ }
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -1822,8 +1877,8 @@ Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root) {
cast<Instruction>(Builder.CreateAdd(Inst, Inst, "tmp.lcssa.user"));
else {
assert(Inst->getType()->isPointerTy());
- Tmp = cast<Instruction>(
- Builder.CreateGEP(Inst, Builder.getInt32(1), "tmp.lcssa.user"));
+ Tmp = cast<Instruction>(Builder.CreatePtrToInt(
+ Inst, Type::getInt32Ty(Inst->getContext()), "tmp.lcssa.user"));
}
V = fixupLCSSAFormFor(Tmp, 0);
@@ -1846,7 +1901,7 @@ Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root) {
ScalarEvolution::ValueOffsetPair
SCEVExpander::FindValueInExprValueMap(const SCEV *S,
const Instruction *InsertPt) {
- SetVector<ScalarEvolution::ValueOffsetPair> *Set = SE.getSCEVValues(S);
+ auto *Set = SE.getSCEVValues(S);
// If the expansion is not in CanonicalMode, and the SCEV contains any
// sub scAddRecExpr type SCEV, it is required to expand the SCEV literally.
if (CanonicalMode || !SE.containsAddRecurrence(S)) {
@@ -2045,8 +2100,9 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
Phi->replaceAllUsesWith(V);
DeadInsts.emplace_back(Phi);
++NumElim;
- DEBUG_WITH_TYPE(DebugType, dbgs()
- << "INDVARS: Eliminated constant iv: " << *Phi << '\n');
+ SCEV_DEBUG_WITH_TYPE(DebugType,
+ dbgs() << "INDVARS: Eliminated constant iv: " << *Phi
+ << '\n');
continue;
}
@@ -2103,9 +2159,9 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
TruncExpr == SE.getSCEV(IsomorphicInc) &&
SE.LI.replacementPreservesLCSSAForm(IsomorphicInc, OrigInc) &&
hoistIVInc(OrigInc, IsomorphicInc)) {
- DEBUG_WITH_TYPE(DebugType,
- dbgs() << "INDVARS: Eliminated congruent iv.inc: "
- << *IsomorphicInc << '\n');
+ SCEV_DEBUG_WITH_TYPE(
+ DebugType, dbgs() << "INDVARS: Eliminated congruent iv.inc: "
+ << *IsomorphicInc << '\n');
Value *NewInc = OrigInc;
if (OrigInc->getType() != IsomorphicInc->getType()) {
Instruction *IP = nullptr;
@@ -2124,10 +2180,11 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
}
}
}
- DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Eliminated congruent iv: "
- << *Phi << '\n');
- DEBUG_WITH_TYPE(DebugType, dbgs() << "INDVARS: Original iv: "
- << *OrigPhiRef << '\n');
+ SCEV_DEBUG_WITH_TYPE(DebugType,
+ dbgs() << "INDVARS: Eliminated congruent iv: " << *Phi
+ << '\n');
+ SCEV_DEBUG_WITH_TYPE(
+ DebugType, dbgs() << "INDVARS: Original iv: " << *OrigPhiRef << '\n');
++NumElim;
Value *NewIV = OrigPhiRef;
if (OrigPhiRef->getType() != Phi->getType()) {
@@ -2179,13 +2236,13 @@ SCEVExpander::getRelatedExistingExpansion(const SCEV *S, const Instruction *At,
return None;
}
-template<typename T> static int costAndCollectOperands(
+template<typename T> static InstructionCost costAndCollectOperands(
const SCEVOperand &WorkItem, const TargetTransformInfo &TTI,
TargetTransformInfo::TargetCostKind CostKind,
SmallVectorImpl<SCEVOperand> &Worklist) {
const T *S = cast<T>(WorkItem.S);
- int Cost = 0;
+ InstructionCost Cost = 0;
// Object to help map SCEV operands to expanded IR instructions.
struct OperationIndices {
OperationIndices(unsigned Opc, size_t min, size_t max) :
@@ -2200,7 +2257,7 @@ template<typename T> static int costAndCollectOperands(
// we know what the generated user(s) will be.
SmallVector<OperationIndices, 2> Operations;
- auto CastCost = [&](unsigned Opcode) {
+ auto CastCost = [&](unsigned Opcode) -> InstructionCost {
Operations.emplace_back(Opcode, 0, 0);
return TTI.getCastInstrCost(Opcode, S->getType(),
S->getOperand(0)->getType(),
@@ -2208,14 +2265,15 @@ template<typename T> static int costAndCollectOperands(
};
auto ArithCost = [&](unsigned Opcode, unsigned NumRequired,
- unsigned MinIdx = 0, unsigned MaxIdx = 1) {
+ unsigned MinIdx = 0,
+ unsigned MaxIdx = 1) -> InstructionCost {
Operations.emplace_back(Opcode, MinIdx, MaxIdx);
return NumRequired *
TTI.getArithmeticInstrCost(Opcode, S->getType(), CostKind);
};
- auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired,
- unsigned MinIdx, unsigned MaxIdx) {
+ auto CmpSelCost = [&](unsigned Opcode, unsigned NumRequired, unsigned MinIdx,
+ unsigned MaxIdx) -> InstructionCost {
Operations.emplace_back(Opcode, MinIdx, MaxIdx);
Type *OpType = S->getOperand(0)->getType();
return NumRequired * TTI.getCmpSelInstrCost(
@@ -2262,6 +2320,7 @@ template<typename T> static int costAndCollectOperands(
case scUMaxExpr:
case scSMinExpr:
case scUMinExpr: {
+ // FIXME: should this ask the cost for Intrinsic's?
Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1);
Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 1, 0, 2);
break;
@@ -2286,10 +2345,11 @@ template<typename T> static int costAndCollectOperands(
// Much like with normal add expr, the polynominal will require
// one less addition than the number of it's terms.
- int AddCost = ArithCost(Instruction::Add, NumTerms - 1,
- /*MinIdx*/1, /*MaxIdx*/1);
+ InstructionCost AddCost = ArithCost(Instruction::Add, NumTerms - 1,
+ /*MinIdx*/ 1, /*MaxIdx*/ 1);
// Here, *each* one of those will require a multiplication.
- int MulCost = ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
+ InstructionCost MulCost =
+ ArithCost(Instruction::Mul, NumNonZeroDegreeNonOneTerms);
Cost = AddCost + MulCost;
// What is the degree of this polynominal?
@@ -2320,10 +2380,10 @@ template<typename T> static int costAndCollectOperands(
bool SCEVExpander::isHighCostExpansionHelper(
const SCEVOperand &WorkItem, Loop *L, const Instruction &At,
- int &BudgetRemaining, const TargetTransformInfo &TTI,
+ InstructionCost &Cost, unsigned Budget, const TargetTransformInfo &TTI,
SmallPtrSetImpl<const SCEV *> &Processed,
SmallVectorImpl<SCEVOperand> &Worklist) {
- if (BudgetRemaining < 0)
+ if (Cost > Budget)
return true; // Already run out of budget, give up.
const SCEV *S = WorkItem.S;
@@ -2353,17 +2413,16 @@ bool SCEVExpander::isHighCostExpansionHelper(
return 0;
const APInt &Imm = cast<SCEVConstant>(S)->getAPInt();
Type *Ty = S->getType();
- BudgetRemaining -= TTI.getIntImmCostInst(
+ Cost += TTI.getIntImmCostInst(
WorkItem.ParentOpcode, WorkItem.OperandIdx, Imm, Ty, CostKind);
- return BudgetRemaining < 0;
+ return Cost > Budget;
}
case scTruncate:
case scPtrToInt:
case scZeroExtend:
case scSignExtend: {
- int Cost =
+ Cost +=
costAndCollectOperands<SCEVCastExpr>(WorkItem, TTI, CostKind, Worklist);
- BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
case scUDivExpr: {
@@ -2379,10 +2438,8 @@ bool SCEVExpander::isHighCostExpansionHelper(
SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), &At, L))
return false; // Consider it to be free.
- int Cost =
+ Cost +=
costAndCollectOperands<SCEVUDivExpr>(WorkItem, TTI, CostKind, Worklist);
- // Need to count the cost of this UDiv.
- BudgetRemaining -= Cost;
return false; // Will answer upon next entry into this function.
}
case scAddExpr:
@@ -2395,17 +2452,16 @@ bool SCEVExpander::isHighCostExpansionHelper(
"Nary expr should have more than 1 operand.");
// The simple nary expr will require one less op (or pair of ops)
// than the number of it's terms.
- int Cost =
+ Cost +=
costAndCollectOperands<SCEVNAryExpr>(WorkItem, TTI, CostKind, Worklist);
- BudgetRemaining -= Cost;
- return BudgetRemaining < 0;
+ return Cost > Budget;
}
case scAddRecExpr: {
assert(cast<SCEVAddRecExpr>(S)->getNumOperands() >= 2 &&
"Polynomial should be at least linear");
- BudgetRemaining -= costAndCollectOperands<SCEVAddRecExpr>(
+ Cost += costAndCollectOperands<SCEVAddRecExpr>(
WorkItem, TTI, CostKind, Worklist);
- return BudgetRemaining < 0;
+ return Cost > Budget;
}
}
llvm_unreachable("Unknown SCEV kind!");
@@ -2473,7 +2529,10 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
Value *StepValue = expandCodeForImpl(Step, Ty, Loc, false);
Value *NegStepValue =
expandCodeForImpl(SE.getNegativeSCEV(Step), Ty, Loc, false);
- Value *StartValue = expandCodeForImpl(Start, ARExpandTy, Loc, false);
+ Value *StartValue = expandCodeForImpl(
+ isa<PointerType>(ARExpandTy) ? Start
+ : SE.getPtrToIntExpr(Start, ARExpandTy),
+ ARExpandTy, Loc, false);
ConstantInt *Zero =
ConstantInt::get(Loc->getContext(), APInt::getNullValue(DstBits));
@@ -2675,14 +2734,13 @@ bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint,
if (InsertionPoint->getParent()->getTerminator() == InsertionPoint)
return true;
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S))
- for (const Value *V : InsertionPoint->operand_values())
- if (V == U->getValue())
- return true;
+ if (llvm::is_contained(InsertionPoint->operand_values(), U->getValue()))
+ return true;
}
return false;
}
-SCEVExpanderCleaner::~SCEVExpanderCleaner() {
+void SCEVExpanderCleaner::cleanup() {
// Result is used, nothing to remove.
if (ResultUsed)
return;