132#define DEBUG_TYPE "loop-reduce"
149 cl::desc(
"Enable LSR phi elimination"));
154 cl::desc(
"Add instruction count to a LSR cost model"));
159 cl::desc(
"Narrow LSR complex solution using"
160 " expectation of registers number"));
166 cl::desc(
"Narrow LSR search space by filtering non-optimal formulae"
167 " with the same ScaledReg and Scale"));
171 cl::desc(
"A flag that overrides the target's preferred addressing mode."),
175 "Prefer pre-indexed addressing mode"),
177 "Prefer post-indexed addressing mode"),
182 cl::init(std::numeric_limits<uint16_t>::max()),
183 cl::desc(
"LSR search space complexity limit"));
187 cl::desc(
"The limit on recursion depth for LSRs setup cost"));
191 cl::desc(
"Attempt to drop solution if it is less profitable"));
195 cl::desc(
"Enable analysis of vscale-relative immediates in LSR"));
199 cl::desc(
"Avoid using scaled registers with vscale-relative addressing"));
205 cl::desc(
"Stress test LSR IV chains"));
215 std::numeric_limits<unsigned>::max();
217 Type *MemTy =
nullptr;
220 MemAccessTy() =
default;
221 MemAccessTy(
Type *Ty,
unsigned AS) : MemTy(Ty), AddrSpace(AS) {}
224 return MemTy ==
Other.MemTy && AddrSpace ==
Other.AddrSpace;
229 static MemAccessTy getUnknown(LLVMContext &Ctx,
230 unsigned AS = UnknownAddressSpace) {
231 return MemAccessTy(Type::getVoidTy(Ctx), AS);
242 SmallBitVector UsedByIndices;
244 void print(raw_ostream &OS)
const;
251 constexpr Immediate(ScalarTy MinVal,
bool Scalable)
252 : FixedOrScalableQuantity(MinVal, Scalable) {}
254 constexpr Immediate(
const FixedOrScalableQuantity<Immediate, int64_t> &V)
255 : FixedOrScalableQuantity(
V) {}
258 constexpr Immediate() =
delete;
260 static constexpr Immediate getFixed(ScalarTy MinVal) {
261 return {MinVal,
false};
263 static constexpr Immediate getScalable(ScalarTy MinVal) {
264 return {MinVal,
true};
266 static constexpr Immediate
get(ScalarTy MinVal,
bool Scalable) {
267 return {MinVal, Scalable};
269 static constexpr Immediate getZero() {
return {0,
false}; }
270 static constexpr Immediate getFixedMin() {
271 return {std::numeric_limits<int64_t>::min(),
false};
273 static constexpr Immediate getFixedMax() {
274 return {std::numeric_limits<int64_t>::max(),
false};
276 static constexpr Immediate getScalableMin() {
277 return {std::numeric_limits<int64_t>::min(),
true};
279 static constexpr Immediate getScalableMax() {
280 return {std::numeric_limits<int64_t>::max(),
true};
283 constexpr bool isLessThanZero()
const {
return Quantity < 0; }
285 constexpr bool isGreaterThanZero()
const {
return Quantity > 0; }
287 constexpr bool isCompatibleImmediate(
const Immediate &Imm)
const {
288 return isZero() ||
Imm.isZero() ||
Imm.Scalable == Scalable;
291 constexpr bool isMin()
const {
292 return Quantity == std::numeric_limits<ScalarTy>::min();
295 constexpr bool isMax()
const {
296 return Quantity == std::numeric_limits<ScalarTy>::max();
300 constexpr Immediate addUnsigned(
const Immediate &
RHS)
const {
301 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
302 ScalarTy
Value = (uint64_t)Quantity +
RHS.getKnownMinValue();
303 return {
Value, Scalable ||
RHS.isScalable()};
306 constexpr Immediate subUnsigned(
const Immediate &
RHS)
const {
307 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
308 ScalarTy
Value = (uint64_t)Quantity -
RHS.getKnownMinValue();
309 return {
Value, Scalable ||
RHS.isScalable()};
313 constexpr Immediate mulUnsigned(
const ScalarTy
RHS)
const {
314 ScalarTy
Value = (uint64_t)Quantity *
RHS;
315 return {
Value, Scalable};
319 const SCEV *getSCEV(ScalarEvolution &SE,
Type *Ty)
const {
326 const SCEV *getNegativeSCEV(ScalarEvolution &SE,
Type *Ty)
const {
327 const SCEV *NegS = SE.
getConstant(Ty, -(uint64_t)Quantity);
333 const SCEV *getUnknownSCEV(ScalarEvolution &SE,
Type *Ty)
const {
348struct KeyOrderTargetImmediate {
349 bool operator()(
const Immediate &
LHS,
const Immediate &
RHS)
const {
350 if (
LHS.isScalable() && !
RHS.isScalable())
352 if (!
LHS.isScalable() &&
RHS.isScalable())
354 return LHS.getKnownMinValue() <
RHS.getKnownMinValue();
361struct KeyOrderSizeTAndImmediate {
362 bool operator()(
const std::pair<size_t, Immediate> &
LHS,
363 const std::pair<size_t, Immediate> &
RHS)
const {
364 size_t LSize =
LHS.first;
365 size_t RSize =
RHS.first;
367 return LSize < RSize;
368 return KeyOrderTargetImmediate()(
LHS.second,
RHS.second);
373#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
375 OS <<
"[NumUses=" << UsedByIndices.
count() <<
']';
387 using RegUsesTy = DenseMap<const SCEV *, RegSortData>;
389 RegUsesTy RegUsesMap;
393 void countRegister(
const SCEV *
Reg,
size_t LUIdx);
394 void dropRegister(
const SCEV *
Reg,
size_t LUIdx);
395 void swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx);
397 bool isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const;
399 const SmallBitVector &getUsedByIndices(
const SCEV *
Reg)
const;
415RegUseTracker::countRegister(
const SCEV *
Reg,
size_t LUIdx) {
416 std::pair<RegUsesTy::iterator, bool> Pair = RegUsesMap.try_emplace(
Reg);
417 RegSortData &RSD = Pair.first->second;
420 RSD.UsedByIndices.
resize(std::max(RSD.UsedByIndices.
size(), LUIdx + 1));
421 RSD.UsedByIndices.
set(LUIdx);
425RegUseTracker::dropRegister(
const SCEV *
Reg,
size_t LUIdx) {
426 RegUsesTy::iterator It = RegUsesMap.find(
Reg);
427 assert(It != RegUsesMap.end());
428 RegSortData &RSD = It->second;
430 RSD.UsedByIndices.
reset(LUIdx);
434RegUseTracker::swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx) {
435 assert(LUIdx <= LastLUIdx);
439 for (
auto &Pair : RegUsesMap) {
440 SmallBitVector &UsedByIndices = Pair.second.UsedByIndices;
441 if (LUIdx < UsedByIndices.
size())
442 UsedByIndices[LUIdx] =
443 LastLUIdx < UsedByIndices.
size() ? UsedByIndices[LastLUIdx] :
false;
444 UsedByIndices.
resize(std::min(UsedByIndices.
size(), LastLUIdx));
449RegUseTracker::isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const {
450 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
451 if (
I == RegUsesMap.end())
453 const SmallBitVector &UsedByIndices =
I->second.UsedByIndices;
455 if (i == -1)
return false;
456 if ((
size_t)i != LUIdx)
return true;
460const SmallBitVector &RegUseTracker::getUsedByIndices(
const SCEV *
Reg)
const {
461 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
462 assert(
I != RegUsesMap.end() &&
"Unknown register!");
463 return I->second.UsedByIndices;
466void RegUseTracker::clear() {
477 GlobalValue *BaseGV =
nullptr;
480 Immediate BaseOffset = Immediate::getZero();
483 bool HasBaseReg =
false;
506 const SCEV *ScaledReg =
nullptr;
511 Immediate UnfoldedOffset = Immediate::getZero();
515 void initialMatch(
const SCEV *S, Loop *L, ScalarEvolution &SE);
519 void canonicalize(
const Loop &L);
523 bool hasZeroEnd()
const;
525 bool countsDownToZero()
const;
527 size_t getNumRegs()
const;
530 void deleteBaseReg(
const SCEV *&S);
532 bool referencesReg(
const SCEV *S)
const;
533 bool hasRegsUsedByUsesOtherThan(
size_t LUIdx,
534 const RegUseTracker &RegUses)
const;
536 void print(raw_ostream &OS)
const;
554 for (
const SCEV *S :
Add->operands())
560 const SCEV *Start, *Step;
575 if (
Mul->getOperand(0)->isAllOnesValue()) {
584 for (
const SCEV *S : MyGood)
586 for (
const SCEV *S : MyBad)
598void Formula::initialMatch(
const SCEV *S, Loop *L, ScalarEvolution &SE) {
605 BaseRegs.push_back(Sum);
611 BaseRegs.push_back(Sum);
626bool Formula::isCanonical(
const Loop &L)
const {
627 assert((Scale == 0 || ScaledReg) &&
628 "ScaledReg must be non-null if Scale is non-zero");
631 return BaseRegs.size() <= 1;
636 if (Scale == 1 && BaseRegs.empty())
645 return none_of(BaseRegs, [&L](
const SCEV *S) {
656void Formula::canonicalize(
const Loop &L) {
660 if (BaseRegs.empty()) {
662 assert(ScaledReg &&
"Expected 1*reg => reg");
663 assert(Scale == 1 &&
"Expected 1*reg => reg");
664 BaseRegs.push_back(ScaledReg);
672 ScaledReg = BaseRegs.pop_back_val();
680 auto I =
find_if(BaseRegs, [&L](
const SCEV *S) {
683 if (
I != BaseRegs.end())
693bool Formula::unscale() {
697 BaseRegs.push_back(ScaledReg);
702bool Formula::hasZeroEnd()
const {
703 if (UnfoldedOffset || BaseOffset)
705 if (BaseRegs.size() != 1 || ScaledReg)
710bool Formula::countsDownToZero()
const {
713 assert(BaseRegs.size() == 1 &&
"hasZeroEnd should mean one BaseReg");
714 const APInt *StepInt;
722size_t Formula::getNumRegs()
const {
723 return !!ScaledReg + BaseRegs.size();
728Type *Formula::getType()
const {
729 return !BaseRegs.empty() ? BaseRegs.front()->getType() :
730 ScaledReg ? ScaledReg->
getType() :
736void Formula::deleteBaseReg(
const SCEV *&S) {
737 if (&S != &BaseRegs.back())
743bool Formula::referencesReg(
const SCEV *S)
const {
749bool Formula::hasRegsUsedByUsesOtherThan(
size_t LUIdx,
750 const RegUseTracker &RegUses)
const {
752 if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
754 for (
const SCEV *BaseReg : BaseRegs)
755 if (RegUses.isRegUsedByUsesOtherThan(BaseReg, LUIdx))
760#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
761void Formula::print(raw_ostream &OS)
const {
762 ListSeparator
Plus(
" + ");
767 if (BaseOffset.isNonZero())
768 OS <<
Plus << BaseOffset;
770 for (
const SCEV *BaseReg : BaseRegs)
773 if (HasBaseReg && BaseRegs.empty())
774 OS <<
Plus <<
"**error: HasBaseReg**";
775 else if (!HasBaseReg && !BaseRegs.empty())
776 OS <<
Plus <<
"**error: !HasBaseReg**";
779 OS <<
Plus << Scale <<
"*reg(";
786 if (UnfoldedOffset.isNonZero())
787 OS <<
Plus <<
"imm(" << UnfoldedOffset <<
')';
827 bool IgnoreSignificantBits =
false) {
838 if (
RA.isAllOnes()) {
839 if (
LHS->getType()->isPointerTy())
852 const APInt &LA =
C->getAPInt();
861 if ((IgnoreSignificantBits ||
isAddRecSExtable(AR, SE)) && AR->isAffine()) {
863 IgnoreSignificantBits);
864 if (!Step)
return nullptr;
866 IgnoreSignificantBits);
867 if (!Start)
return nullptr;
880 for (
const SCEV *S :
Add->operands()) {
882 if (!
Op)
return nullptr;
910 for (
const SCEV *S :
Mul->operands()) {
913 IgnoreSignificantBits)) {
933 bool PreferScalable) {
936 Immediate Result = Immediate::getZero();
945 C->getSignificantBits() <= 64) {
947 Result = Immediate::getFixed(
C->getSExtValue());
959 Result = Immediate::getScalable(
C->getSExtValue());
965 if (Result.isNonZero()) {
976 bool PreferScalable =
false) {
982 if (Result.isNonZero())
988 if (Result.isNonZero())
1029 if (
SI->getPointerOperand() == OperandVal)
1034 switch (
II->getIntrinsicID()) {
1035 case Intrinsic::memset:
1036 case Intrinsic::prefetch:
1037 case Intrinsic::masked_load:
1038 if (
II->getArgOperand(0) == OperandVal)
1041 case Intrinsic::masked_store:
1042 if (
II->getArgOperand(1) == OperandVal)
1045 case Intrinsic::memmove:
1046 case Intrinsic::memcpy:
1047 if (
II->getArgOperand(0) == OperandVal ||
1048 II->getArgOperand(1) == OperandVal)
1053 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo)) {
1054 if (IntrInfo.
PtrVal == OperandVal)
1060 if (RMW->getPointerOperand() == OperandVal)
1063 if (CmpX->getPointerOperand() == OperandVal)
1072 MemAccessTy AccessTy = MemAccessTy::getUnknown(Inst->
getContext());
1076 AccessTy.MemTy = Ty;
1080 AccessTy.AddrSpace =
SI->getPointerAddressSpace();
1082 AccessTy.AddrSpace = LI->getPointerAddressSpace();
1084 AccessTy.AddrSpace = RMW->getPointerAddressSpace();
1086 AccessTy.AddrSpace = CmpX->getPointerAddressSpace();
1088 switch (
II->getIntrinsicID()) {
1089 case Intrinsic::prefetch:
1090 case Intrinsic::memset:
1091 AccessTy.AddrSpace =
II->getArgOperand(0)->getType()->getPointerAddressSpace();
1092 AccessTy.MemTy = OperandVal->
getType();
1094 case Intrinsic::memmove:
1095 case Intrinsic::memcpy:
1097 AccessTy.MemTy = OperandVal->
getType();
1099 case Intrinsic::masked_load:
1100 AccessTy.AddrSpace =
1101 II->getArgOperand(0)->getType()->getPointerAddressSpace();
1103 case Intrinsic::masked_store:
1104 AccessTy.AddrSpace =
1105 II->getArgOperand(1)->getType()->getPointerAddressSpace();
1109 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo) && IntrInfo.
PtrVal) {
1165 if (!Processed.
insert(S).second)
1169 for (
const SCEV *S :
Add->operands()) {
1176 const SCEV *Op0, *Op1;
1185 Value *UVal = U->getValue();
1189 if (UI && UI->
getOpcode() == Instruction::Mul &&
1222 const LSRUse &LU,
const Formula &
F);
1226 const LSRUse &LU,
const Formula &
F,
1233 const Loop *
L =
nullptr;
1234 ScalarEvolution *SE =
nullptr;
1235 const TargetTransformInfo *
TTI =
nullptr;
1236 TargetTransformInfo::LSRCost
C;
1241 Cost(
const Loop *L, ScalarEvolution &SE,
const TargetTransformInfo &
TTI,
1243 L(
L), SE(&SE),
TTI(&
TTI), AMK(AMK) {
1261 return ((
C.Insns |
C.NumRegs |
C.AddRecCost |
C.NumIVMuls |
C.NumBaseAdds
1262 |
C.ImmCost |
C.SetupCost |
C.ScaleCost) != ~0u)
1263 || ((
C.Insns &
C.NumRegs &
C.AddRecCost &
C.NumIVMuls &
C.NumBaseAdds
1264 &
C.ImmCost &
C.SetupCost &
C.ScaleCost) == ~0
u);
1270 return C.NumRegs == ~0
u;
1273 void RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1274 const DenseSet<const SCEV *> &VisitedRegs,
const LSRUse &LU,
1275 bool HardwareLoopProfitable,
1276 SmallPtrSetImpl<const SCEV *> *LoserRegs =
nullptr);
1278 void print(raw_ostream &OS)
const;
1282 void RateRegister(
const Formula &
F,
const SCEV *
Reg,
1283 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1284 bool HardwareLoopProfitable);
1285 void RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1286 SmallPtrSetImpl<const SCEV *> &Regs,
1287 const LSRUse &LU,
bool HardwareLoopProfitable,
1288 SmallPtrSetImpl<const SCEV *> *LoserRegs);
1299 Value *OperandValToReplace =
nullptr;
1309 Immediate
Offset = Immediate::getZero();
1311 LSRFixup() =
default;
1313 bool isUseFullyOutsideLoop(
const Loop *L)
const;
1315 void print(raw_ostream &OS)
const;
1325 DenseSet<SmallVector<const SCEV *, 4>> Uniquifier;
1338 using SCEVUseKindPair = PointerIntPair<const SCEV *, 2, KindType>;
1341 MemAccessTy AccessTy;
1347 Immediate MinOffset = Immediate::getFixedMax();
1348 Immediate MaxOffset = Immediate::getFixedMin();
1352 bool AllFixupsOutsideLoop =
true;
1357 bool AllFixupsUnconditional =
true;
1364 bool RigidFormula =
false;
1372 SmallPtrSet<const SCEV *, 4> Regs;
1374 LSRUse(KindType K, MemAccessTy AT) :
Kind(
K), AccessTy(AT) {}
1376 LSRFixup &getNewFixup() {
1377 Fixups.push_back(LSRFixup());
1381 void pushFixup(LSRFixup &f) {
1383 if (Immediate::isKnownGT(
f.Offset, MaxOffset))
1384 MaxOffset =
f.Offset;
1385 if (Immediate::isKnownLT(
f.Offset, MinOffset))
1386 MinOffset =
f.Offset;
1389 bool HasFormulaWithSameRegs(
const Formula &
F)
const;
1390 float getNotSelectedProbability(
const SCEV *
Reg)
const;
1391 bool InsertFormula(
const Formula &
F,
const Loop &L);
1392 void DeleteFormula(Formula &
F);
1393 void RecomputeRegs(
size_t LUIdx, RegUseTracker &Reguses);
1395 void print(raw_ostream &OS)
const;
1402 LSRUse::KindType Kind, MemAccessTy AccessTy,
1403 GlobalValue *BaseGV, Immediate BaseOffset,
1404 bool HasBaseReg, int64_t Scale,
1405 Instruction *
Fixup =
nullptr);
1412 if (
TTI.getIntImmCost(
C->getAPInt(),
C->getType(),
1426 [&](
unsigned i,
const SCEV *
Reg) {
1427 return i + getSetupCost(Reg, Depth - 1, TTI);
1436void Cost::RateRegister(
const Formula &
F,
const SCEV *
Reg,
1437 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1438 bool HardwareLoopProfitable) {
1443 if (AR->getLoop() != L) {
1450 if (!AR->getLoop()->contains(L)) {
1460 unsigned LoopCost = 1;
1469 F.BaseOffset.isFixed() &&
1470 *Step ==
F.BaseOffset.getFixedValue();
1475 if ((CanPreIndex || CanPostIndex) && LU.AllFixupsUnconditional)
1482 if (LU.Kind == LSRUse::ICmpZero &&
F.countsDownToZero() &&
1483 HardwareLoopProfitable)
1485 C.AddRecCost += LoopCost;
1489 const SCEV *StepReg = AR->getOperand(1);
1494 auto IsVScaleStep = [](
const SCEV *
Reg,
const TargetTransformInfo *
TTI) {
1500 if (!Regs.
count(StepReg) && !IsVScaleStep(StepReg,
TTI)) {
1501 RateRegister(
F, StepReg, Regs, LU, HardwareLoopProfitable);
1513 C.SetupCost = std::min<unsigned>(
C.SetupCost, 1 << 16);
1522void Cost::RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1523 SmallPtrSetImpl<const SCEV *> &Regs,
1524 const LSRUse &LU,
bool HardwareLoopProfitable,
1525 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1526 if (LoserRegs && LoserRegs->
count(
Reg)) {
1531 RateRegister(
F,
Reg, Regs, LU, HardwareLoopProfitable);
1532 if (LoserRegs && isLoser())
1537void Cost::RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1538 const DenseSet<const SCEV *> &VisitedRegs,
1539 const LSRUse &LU,
bool HardwareLoopProfitable,
1540 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1543 assert(
F.isCanonical(*L) &&
"Cost is accurate only for canonical formula");
1545 unsigned PrevAddRecCost =
C.AddRecCost;
1546 unsigned PrevNumRegs =
C.NumRegs;
1547 unsigned PrevNumBaseAdds =
C.NumBaseAdds;
1548 if (
const SCEV *ScaledReg =
F.ScaledReg) {
1549 if (VisitedRegs.
count(ScaledReg)) {
1553 RatePrimaryRegister(
F, ScaledReg, Regs, LU, HardwareLoopProfitable,
1558 for (
const SCEV *BaseReg :
F.BaseRegs) {
1559 if (VisitedRegs.
count(BaseReg)) {
1563 RatePrimaryRegister(
F, BaseReg, Regs, LU, HardwareLoopProfitable,
1570 size_t NumBaseParts =
F.getNumRegs();
1571 if (NumBaseParts > 1)
1576 C.NumBaseAdds += (
F.UnfoldedOffset.isNonZero());
1582 for (
const LSRFixup &
Fixup : LU.Fixups) {
1583 if (
Fixup.Offset.isCompatibleImmediate(
F.BaseOffset)) {
1584 Immediate
Offset =
Fixup.Offset.addUnsigned(
F.BaseOffset);
1588 else if (
Offset.isNonZero())
1590 APInt(64,
Offset.getKnownMinValue(),
true).getSignificantBits();
1594 if (LU.Kind == LSRUse::Address &&
Offset.isNonZero() &&
1615 if (
C.NumRegs > TTIRegNum) {
1618 if (PrevNumRegs > TTIRegNum)
1619 C.Insns += (
C.NumRegs - PrevNumRegs);
1621 C.Insns += (
C.NumRegs - TTIRegNum);
1634 if (LU.Kind == LSRUse::ICmpZero && !
F.hasZeroEnd() &&
1638 C.Insns += (
C.AddRecCost - PrevAddRecCost);
1641 if (LU.Kind != LSRUse::ICmpZero)
1642 C.Insns +=
C.NumBaseAdds - PrevNumBaseAdds;
1648 C.Insns = std::numeric_limits<unsigned>::max();
1649 C.NumRegs = std::numeric_limits<unsigned>::max();
1650 C.AddRecCost = std::numeric_limits<unsigned>::max();
1651 C.NumIVMuls = std::numeric_limits<unsigned>::max();
1652 C.NumBaseAdds = std::numeric_limits<unsigned>::max();
1653 C.ImmCost = std::numeric_limits<unsigned>::max();
1654 C.SetupCost = std::numeric_limits<unsigned>::max();
1655 C.ScaleCost = std::numeric_limits<unsigned>::max();
1659bool Cost::isLess(
const Cost &
Other)
const {
1661 C.Insns !=
Other.C.Insns)
1662 return C.Insns <
Other.C.Insns;
1666#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1669 OS <<
C.Insns <<
" instruction" << (
C.Insns == 1 ?
" " :
"s ");
1670 OS <<
C.NumRegs <<
" reg" << (
C.NumRegs == 1 ?
"" :
"s");
1671 if (
C.AddRecCost != 0)
1672 OS <<
", with addrec cost " <<
C.AddRecCost;
1673 if (
C.NumIVMuls != 0)
1674 OS <<
", plus " <<
C.NumIVMuls <<
" IV mul"
1675 << (
C.NumIVMuls == 1 ?
"" :
"s");
1676 if (
C.NumBaseAdds != 0)
1677 OS <<
", plus " <<
C.NumBaseAdds <<
" base add"
1678 << (
C.NumBaseAdds == 1 ?
"" :
"s");
1679 if (
C.ScaleCost != 0)
1680 OS <<
", plus " <<
C.ScaleCost <<
" scale cost";
1682 OS <<
", plus " <<
C.ImmCost <<
" imm cost";
1683 if (
C.SetupCost != 0)
1684 OS <<
", plus " <<
C.SetupCost <<
" setup cost";
1693bool LSRFixup::isUseFullyOutsideLoop(
const Loop *L)
const {
1696 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1697 if (PN->getIncomingValue(i) == OperandValToReplace &&
1698 L->contains(PN->getIncomingBlock(i)))
1703 return !
L->contains(UserInst);
1706#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1707void LSRFixup::print(raw_ostream &OS)
const {
1712 Store->getOperand(0)->printAsOperand(OS,
false);
1718 OS <<
", OperandValToReplace=";
1721 for (
const Loop *PIL : PostIncLoops) {
1722 OS <<
", PostIncLoop=";
1723 PIL->getHeader()->printAsOperand(OS,
false);
1727 OS <<
", Offset=" <<
Offset;
1737bool LSRUse::HasFormulaWithSameRegs(
const Formula &
F)
const {
1739 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1746float LSRUse::getNotSelectedProbability(
const SCEV *
Reg)
const {
1748 for (
const Formula &
F : Formulae)
1749 if (
F.referencesReg(
Reg))
1751 return ((
float)(Formulae.size() - FNum)) / Formulae.size();
1756bool LSRUse::InsertFormula(
const Formula &
F,
const Loop &L) {
1757 assert(
F.isCanonical(L) &&
"Invalid canonical representation");
1759 if (!Formulae.empty() && RigidFormula)
1763 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1771 assert((!
F.ScaledReg || !
F.ScaledReg->isZero()) &&
1772 "Zero allocated in a scaled register!");
1774 for (
const SCEV *BaseReg :
F.BaseRegs)
1775 assert(!
BaseReg->isZero() &&
"Zero allocated in a base register!");
1779 Formulae.push_back(
F);
1790void LSRUse::DeleteFormula(Formula &
F) {
1791 if (&
F != &Formulae.back())
1793 Formulae.pop_back();
1797void LSRUse::RecomputeRegs(
size_t LUIdx, RegUseTracker &RegUses) {
1799 SmallPtrSet<const SCEV *, 4> OldRegs = std::move(Regs);
1801 for (
const Formula &
F : Formulae) {
1802 if (
F.ScaledReg) Regs.
insert(
F.ScaledReg);
1807 for (
const SCEV *S : OldRegs)
1809 RegUses.dropRegister(S, LUIdx);
1812#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1813void LSRUse::print(raw_ostream &OS)
const {
1814 OS <<
"LSR Use: Kind=";
1816 case Basic: OS <<
"Basic";
break;
1817 case Special: OS <<
"Special";
break;
1818 case ICmpZero: OS <<
"ICmpZero";
break;
1820 OS <<
"Address of ";
1824 OS << *AccessTy.MemTy;
1827 OS <<
" in addrspace(" << AccessTy.AddrSpace <<
')';
1830 OS <<
", Offsets={";
1831 bool NeedComma =
false;
1832 for (
const LSRFixup &
Fixup : Fixups) {
1833 if (NeedComma) OS <<
',';
1839 if (AllFixupsOutsideLoop)
1840 OS <<
", all-fixups-outside-loop";
1842 if (AllFixupsUnconditional)
1843 OS <<
", all-fixups-unconditional";
1852 LSRUse::KindType Kind, MemAccessTy AccessTy,
1854 bool HasBaseReg, int64_t Scale,
1857 case LSRUse::Address: {
1858 int64_t FixedOffset =
1859 BaseOffset.isScalable() ? 0 : BaseOffset.getFixedValue();
1860 int64_t ScalableOffset =
1861 BaseOffset.isScalable() ? BaseOffset.getKnownMinValue() : 0;
1862 return TTI.isLegalAddressingMode(AccessTy.MemTy, BaseGV, FixedOffset,
1863 HasBaseReg, Scale, AccessTy.AddrSpace,
1864 Fixup, ScalableOffset);
1866 case LSRUse::ICmpZero:
1873 if (Scale != 0 && HasBaseReg && BaseOffset.isNonZero())
1878 if (Scale != 0 && Scale != -1)
1883 if (BaseOffset.isNonZero()) {
1886 if (BaseOffset.isScalable())
1896 BaseOffset = BaseOffset.getFixed(-(
uint64_t)BaseOffset.getFixedValue());
1897 return TTI.isLegalICmpImmediate(BaseOffset.getFixedValue());
1905 return !BaseGV && Scale == 0 && BaseOffset.isZero();
1907 case LSRUse::Special:
1909 return !BaseGV && (Scale == 0 || Scale == -1) && BaseOffset.isZero();
1916 Immediate MinOffset, Immediate MaxOffset,
1917 LSRUse::KindType Kind, MemAccessTy AccessTy,
1919 bool HasBaseReg, int64_t Scale) {
1920 if (BaseOffset.isNonZero() &&
1921 (BaseOffset.isScalable() != MinOffset.isScalable() ||
1922 BaseOffset.isScalable() != MaxOffset.isScalable()))
1925 int64_t
Base = BaseOffset.getKnownMinValue();
1926 int64_t Min = MinOffset.getKnownMinValue();
1927 int64_t Max = MaxOffset.getKnownMinValue();
1930 MinOffset = Immediate::get((
uint64_t)
Base + Min, MinOffset.isScalable());
1933 MaxOffset = Immediate::get((
uint64_t)
Base + Max, MaxOffset.isScalable());
1936 HasBaseReg, Scale) &&
1942 Immediate MinOffset, Immediate MaxOffset,
1943 LSRUse::KindType Kind, MemAccessTy AccessTy,
1944 const Formula &
F,
const Loop &L) {
1952 assert((
F.isCanonical(L) ||
F.Scale != 0));
1954 F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
F.Scale);
1959 Immediate MaxOffset, LSRUse::KindType Kind,
1961 Immediate BaseOffset,
bool HasBaseReg, int64_t Scale) {
1964 BaseOffset, HasBaseReg, Scale) ||
1969 BaseGV, BaseOffset,
true, 0));
1973 Immediate MaxOffset, LSRUse::KindType Kind,
1974 MemAccessTy AccessTy,
const Formula &
F) {
1975 return isLegalUse(
TTI, MinOffset, MaxOffset, Kind, AccessTy,
F.BaseGV,
1976 F.BaseOffset,
F.HasBaseReg,
F.Scale);
1982 return TTI.isLegalAddScalableImmediate(
Offset.getKnownMinValue());
1984 return TTI.isLegalAddImmediate(
Offset.getFixedValue());
1988 const LSRUse &LU,
const Formula &
F) {
1990 if (LU.Kind == LSRUse::Address &&
TTI.LSRWithInstrQueries()) {
1991 for (
const LSRFixup &
Fixup : LU.Fixups)
1993 (
F.BaseOffset +
Fixup.Offset),
F.HasBaseReg,
1994 F.Scale,
Fixup.UserInst))
2000 LU.AccessTy,
F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
2005 const LSRUse &LU,
const Formula &
F,
2014 return F.Scale != 1;
2017 case LSRUse::Address: {
2019 int64_t ScalableMin = 0, ScalableMax = 0, FixedMin = 0, FixedMax = 0;
2020 if (
F.BaseOffset.isScalable()) {
2021 ScalableMin = (
F.BaseOffset + LU.MinOffset).getKnownMinValue();
2022 ScalableMax = (
F.BaseOffset + LU.MaxOffset).getKnownMinValue();
2024 FixedMin = (
F.BaseOffset + LU.MinOffset).getFixedValue();
2025 FixedMax = (
F.BaseOffset + LU.MaxOffset).getFixedValue();
2029 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
2032 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
2035 "Legal addressing mode has an illegal cost!");
2036 return std::max(ScaleCostMinOffset, ScaleCostMaxOffset);
2038 case LSRUse::ICmpZero:
2040 case LSRUse::Special:
2050 LSRUse::KindType Kind, MemAccessTy AccessTy,
2054 if (BaseOffset.isZero() && !BaseGV)
2059 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2063 if (!HasBaseReg && Scale == 1) {
2073 if (HasBaseReg && BaseOffset.isNonZero() && Kind != LSRUse::ICmpZero &&
2083 Immediate MaxOffset, LSRUse::KindType Kind,
2084 MemAccessTy AccessTy,
const SCEV *S,
2087 if (S->
isZero())
return true;
2100 if (BaseOffset.isZero() && !BaseGV)
2103 if (BaseOffset.isScalable())
2108 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2111 BaseOffset, HasBaseReg, Scale);
2128 const SCEV *IncExpr;
2130 IVInc(Instruction *U,
Value *O,
const SCEV *
E)
2131 : UserInst(
U), IVOperand(
O), IncExpr(
E) {}
2138 const SCEV *ExprBase =
nullptr;
2140 IVChain() =
default;
2141 IVChain(
const IVInc &Head,
const SCEV *
Base)
2142 : Incs(1, Head), ExprBase(
Base) {}
2147 const_iterator
begin()
const {
2149 return std::next(Incs.
begin());
2151 const_iterator
end()
const {
2156 bool hasIncs()
const {
return Incs.
size() >= 2; }
2165 bool isProfitableIncrement(
const SCEV *OperExpr,
2166 const SCEV *IncExpr,
2174 SmallPtrSet<Instruction*, 4> FarUsers;
2175 SmallPtrSet<Instruction*, 4> NearUsers;
2181 ScalarEvolution &SE;
2184 AssumptionCache &AC;
2185 TargetLibraryInfo &TLI;
2186 const TargetTransformInfo &
TTI;
2188 MemorySSAUpdater *MSSAU;
2192 bool HardwareLoopProfitable =
false;
2193 bool ShouldPreserveLCSSA =
false;
2207 SetVector<int64_t, SmallVector<int64_t, 8>, SmallSet<int64_t, 8>> Factors;
2214 SmallSetVector<Type *, 4> Types;
2220 RegUseTracker RegUses;
2225 static const unsigned MaxChains = 8;
2231 SmallPtrSet<Use*, MaxChains> IVIncSet;
2234 SmallVector<llvm::WeakVH, 2> ScalarEvolutionIVs;
2240 SmallSetVector<Instruction *, 4> InsertedNonLCSSAInsts;
2242 void OptimizeShadowIV();
2243 bool FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse);
2245 void OptimizeLoopTermCond();
2247 void ChainInstruction(Instruction *UserInst, Instruction *IVOper,
2248 SmallVectorImpl<ChainUsers> &ChainUsersVec);
2249 void FinalizeChain(IVChain &Chain);
2250 void CollectChains();
2251 void GenerateIVChain(
const IVChain &Chain,
2252 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2254 void CollectInterestingTypesAndFactors();
2255 void CollectFixupsAndInitialFormulae();
2258 using UseMapTy = DenseMap<LSRUse::SCEVUseKindPair, size_t>;
2261 bool reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
bool HasBaseReg,
2262 LSRUse::KindType Kind, MemAccessTy AccessTy);
2264 std::pair<size_t, Immediate> getUse(
const SCEV *&Expr, LSRUse::KindType Kind,
2265 MemAccessTy AccessTy);
2267 void DeleteUse(LSRUse &LU,
size_t LUIdx);
2269 LSRUse *FindUseWithSimilarFormula(
const Formula &
F,
const LSRUse &OrigLU);
2271 void InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2272 void InsertSupplementalFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2273 void CountRegisters(
const Formula &
F,
size_t LUIdx);
2274 bool InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F);
2275 bool IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const;
2277 void CollectLoopInvariantFixupsAndFormulae();
2279 void GenerateReassociations(LSRUse &LU,
unsigned LUIdx, Formula
Base,
2280 unsigned Depth = 0);
2282 void GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
2284 size_t Idx,
bool IsScaledReg =
false);
2285 void GenerateCombinations(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2286 void GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2287 const Formula &
Base,
size_t Idx,
2288 bool IsScaledReg =
false);
2289 void GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2290 void GenerateConstantOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2291 const Formula &
Base,
2292 const SmallVectorImpl<Immediate> &Worklist,
2293 size_t Idx,
bool IsScaledReg =
false);
2294 void GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2295 void GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2296 void GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2297 void GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2298 void GenerateCrossUseConstantOffsets();
2299 void GenerateAllReuseFormulae();
2301 void FilterOutUndesirableDedicatedRegisters();
2303 size_t EstimateSearchSpaceComplexity()
const;
2304 void NarrowSearchSpaceByDetectingSupersets();
2305 void NarrowSearchSpaceByCollapsingUnrolledCode();
2306 void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
2307 void NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
2308 void NarrowSearchSpaceByFilterPostInc();
2309 void NarrowSearchSpaceByMergingUsesOutsideLoop();
2310 void NarrowSearchSpaceByDeletingCostlyFormulas();
2311 void NarrowSearchSpaceByPickingWinnerRegs();
2312 void NarrowSearchSpaceUsingHeuristics();
2314 void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
2316 SmallVectorImpl<const Formula *> &Workspace,
2317 const Cost &CurCost,
2318 const SmallPtrSet<const SCEV *, 16> &CurRegs,
2319 DenseSet<const SCEV *> &VisitedRegs)
const;
2320 void Solve(SmallVectorImpl<const Formula *> &Solution)
const;
2324 const SmallVectorImpl<Instruction *> &Inputs)
const;
2327 const LSRUse &LU)
const;
2329 Value *Expand(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2331 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const;
2332 void RewriteForPHI(PHINode *PN,
const LSRUse &LU,
const LSRFixup &LF,
2334 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2335 void Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2336 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2337 void ImplementSolution(
const SmallVectorImpl<const Formula *> &Solution);
2344 LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE, DominatorTree &DT,
2345 LoopInfo &LI,
const TargetTransformInfo &
TTI, AssumptionCache &AC,
2346 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
2347 bool PreserveLCSSA);
2349 bool getChanged()
const {
return Changed; }
2350 const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs()
const {
2351 return ScalarEvolutionIVs;
2354 void print_factors_and_types(raw_ostream &OS)
const;
2355 void print_fixups(raw_ostream &OS)
const;
2356 void print_uses(raw_ostream &OS)
const;
2357 void print(raw_ostream &OS)
const;
2365void LSRInstance::OptimizeShadowIV() {
2375 Type *DestTy =
nullptr;
2376 bool IsSigned =
false;
2392 DestTy = UCast->getDestTy();
2396 DestTy = SCast->getDestTy();
2398 if (!DestTy)
continue;
2418 if (Mantissa == -1)
continue;
2422 unsigned Entry, Latch;
2432 if (!Init)
continue;
2433 Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
2437 BinaryOperator *Incr =
2439 if (!Incr)
continue;
2440 if (Incr->
getOpcode() != Instruction::Add
2441 && Incr->
getOpcode() != Instruction::Sub)
2445 ConstantInt *
C =
nullptr;
2457 if (!
C->getValue().isStrictlyPositive())
2465 Constant *CFP = ConstantFP::get(DestTy,
C->getZExtValue());
2467 Incr->
getOpcode() == Instruction::Add ? Instruction::FAdd
2468 : Instruction::FSub,
2485bool LSRInstance::FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse) {
2486 for (IVStrideUse &U : IU)
2487 if (
U.getUser() ==
Cond) {
2545Instruction *LSRInstance::OptimizeMax(ICmpInst *
Cond, IVStrideUse *&CondUse) {
2560 const SCEV *IterationCount = SE.
getAddExpr(One, BackedgeTakenCount);
2561 if (IterationCount != SE.
getSCEV(Sel))
return Cond;
2567 const SCEVNAryExpr *
Max =
nullptr;
2569 Pred = ICmpInst::ICMP_SLE;
2572 Pred = ICmpInst::ICMP_SLT;
2575 Pred = ICmpInst::ICMP_ULT;
2584 if (
Max->getNumOperands() != 2)
2587 const SCEV *MaxLHS =
Max->getOperand(0);
2588 const SCEV *MaxRHS =
Max->getOperand(1);
2593 (ICmpInst::isTrueWhenEqual(Pred) ? !MaxLHS->
isZero() : (MaxLHS != One)))
2604 "Loop condition operand is an addrec in a different loop!");
2608 Value *NewRHS =
nullptr;
2609 if (ICmpInst::isTrueWhenEqual(Pred)) {
2613 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2614 NewRHS = BO->getOperand(0);
2617 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2618 NewRHS = BO->getOperand(0);
2626 NewRHS = SU->getValue();
2638 ICmpInst *NewCond =
new ICmpInst(
Cond->getIterator(), Pred,
2639 Cond->getOperand(0), NewRHS,
"scmp");
2643 Cond->replaceAllUsesWith(NewCond);
2646 Cond->eraseFromParent();
2648 if (
Cmp->use_empty()) {
2650 Cmp->eraseFromParent();
2657LSRInstance::OptimizeLoopTermCond() {
2658 SmallPtrSet<Instruction *, 4> PostIncs;
2673 SmallVector<BasicBlock*, 8> ExitingBlocks;
2674 L->getExitingBlocks(ExitingBlocks);
2682 for (BasicBlock *ExitingBlock : ExitingBlocks) {
2704 IVStrideUse *CondUse =
nullptr;
2705 if (!FindIVUserForCond(
Cond, CondUse))
2715 Cond = OptimizeMax(Cmp, CondUse);
2720 if (!DT.
dominates(ExitingBlock, LatchBlock))
2725 if (LatchBlock != ExitingBlock)
2726 for (
const IVStrideUse &UI : IU)
2729 if (&UI != CondUse &&
2733 const SCEV *
A = IU.getStride(*CondUse, L);
2734 const SCEV *
B = IU.getStride(UI, L);
2735 if (!
A || !
B)
continue;
2744 if (
const SCEVConstant *
D =
2746 const ConstantInt *
C =
D->getValue();
2748 if (
C->isOne() ||
C->isMinusOne())
2749 goto decline_post_inc;
2751 if (
C->getValue().getSignificantBits() >= 64 ||
2752 C->getValue().isMinSignedValue())
2753 goto decline_post_inc;
2756 MemAccessTy AccessTy =
2758 int64_t Scale =
C->getSExtValue();
2762 AccessTy.AddrSpace))
2763 goto decline_post_inc;
2768 AccessTy.AddrSpace))
2769 goto decline_post_inc;
2774 LLVM_DEBUG(
dbgs() <<
" Change loop exiting icmp to use postinc iv: "
2782 if (
Cond->hasOneUse()) {
2783 Cond->moveBefore(TermBr->getIterator());
2788 Cond->setName(
L->getHeader()->getName() +
".termcond");
2789 Cond->insertInto(ExitingBlock, TermBr->getIterator());
2793 TermBr->replaceUsesOfWith(OldCond,
Cond);
2810 IVIncInsertPos =
L->getLoopLatch()->getTerminator();
2811 for (Instruction *Inst : PostIncs)
2817bool LSRInstance::reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
2818 bool HasBaseReg, LSRUse::KindType Kind,
2819 MemAccessTy AccessTy) {
2820 Immediate NewMinOffset = LU.MinOffset;
2821 Immediate NewMaxOffset = LU.MaxOffset;
2822 MemAccessTy NewAccessTy = AccessTy;
2827 if (LU.Kind != Kind)
2833 if (Kind == LSRUse::Address) {
2834 if (AccessTy.MemTy != LU.AccessTy.MemTy) {
2835 NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->
getContext(),
2836 AccessTy.AddrSpace);
2841 if (Immediate::isKnownLT(NewOffset, LU.MinOffset)) {
2843 LU.MaxOffset - NewOffset, HasBaseReg))
2845 NewMinOffset = NewOffset;
2846 }
else if (Immediate::isKnownGT(NewOffset, LU.MaxOffset)) {
2848 NewOffset - LU.MinOffset, HasBaseReg))
2850 NewMaxOffset = NewOffset;
2856 if (NewAccessTy.MemTy && NewAccessTy.MemTy->
isVoidTy() &&
2857 (NewMinOffset.isScalable() || NewMaxOffset.isScalable()))
2861 LU.MinOffset = NewMinOffset;
2862 LU.MaxOffset = NewMaxOffset;
2863 LU.AccessTy = NewAccessTy;
2870std::pair<size_t, Immediate> LSRInstance::getUse(
const SCEV *&Expr,
2871 LSRUse::KindType Kind,
2872 MemAccessTy AccessTy) {
2873 const SCEV *
Copy = Expr;
2876 ExprUse, SE, AccessTy.MemTy && AccessTy.MemTy->
isScalableTy());
2883 Offset = Immediate::getFixed(0);
2886 std::pair<UseMapTy::iterator, bool>
P =
2887 UseMap.
try_emplace(LSRUse::SCEVUseKindPair(Expr, Kind));
2890 size_t LUIdx =
P.first->second;
2891 LSRUse &LU =
Uses[LUIdx];
2892 if (reconcileNewOffset(LU,
Offset,
true, Kind, AccessTy))
2894 return std::make_pair(LUIdx,
Offset);
2898 size_t LUIdx =
Uses.size();
2899 P.first->second = LUIdx;
2900 Uses.push_back(LSRUse(Kind, AccessTy));
2901 LSRUse &LU =
Uses[LUIdx];
2905 return std::make_pair(LUIdx,
Offset);
2909void LSRInstance::DeleteUse(LSRUse &LU,
size_t LUIdx) {
2910 if (&LU != &
Uses.back())
2915 RegUses.swapAndDropUse(LUIdx,
Uses.size());
2921LSRInstance::FindUseWithSimilarFormula(
const Formula &OrigF,
2922 const LSRUse &OrigLU) {
2924 for (LSRUse &LU :
Uses) {
2930 if (&LU != &OrigLU && LU.Kind != LSRUse::ICmpZero &&
2931 LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
2932 LU.HasFormulaWithSameRegs(OrigF)) {
2934 for (
const Formula &
F : LU.Formulae) {
2937 if (
F.BaseRegs == OrigF.BaseRegs &&
2938 F.ScaledReg == OrigF.ScaledReg &&
2939 F.BaseGV == OrigF.BaseGV &&
2940 F.Scale == OrigF.Scale &&
2941 F.UnfoldedOffset == OrigF.UnfoldedOffset) {
2942 if (
F.BaseOffset.isZero())
2957void LSRInstance::CollectInterestingTypesAndFactors() {
2958 SmallSetVector<const SCEV *, 4> Strides;
2962 for (
const IVStrideUse &U : IU) {
2963 const SCEV *Expr = IU.getExpr(U);
2981 }
while (!Worklist.
empty());
2985 for (SmallSetVector<const SCEV *, 4>::const_iterator
2987 for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
2988 std::next(
I); NewStrideIter !=
E; ++NewStrideIter) {
2989 const SCEV *OldStride = *
I;
2990 const SCEV *NewStride = *NewStrideIter;
3000 if (
const SCEVConstant *Factor =
3003 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
3004 Factors.insert(Factor->getAPInt().getSExtValue());
3005 }
else if (
const SCEVConstant *Factor =
3009 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
3010 Factors.insert(Factor->getAPInt().getSExtValue());
3016 if (Types.size() == 1)
3028 for(; OI != OE; ++OI) {
3047 return Trunc->getOperand(0);
3080 if (SubExpr->getSCEVType() ==
scAddExpr)
3083 if (SubExpr->getSCEVType() !=
scMulExpr)
3099bool IVChain::isProfitableIncrement(
const SCEV *OperExpr,
3100 const SCEV *IncExpr,
3101 ScalarEvolution &SE) {
3114 SmallPtrSet<const SCEV*, 8> Processed;
3135 if (!Chain.hasIncs())
3138 if (!
Users.empty()) {
3139 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" users:\n";
3141 :
Users) {
dbgs() <<
" " << *Inst <<
"\n"; });
3144 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3153 && SE.
getSCEV(Chain.tailUserInst()) == Chain.Incs[0].IncExpr) {
3156 const SCEV *LastIncExpr =
nullptr;
3157 unsigned NumConstIncrements = 0;
3158 unsigned NumVarIncrements = 0;
3159 unsigned NumReusedIncrements = 0;
3161 if (
TTI.isProfitableLSRChainElement(Chain.Incs[0].UserInst))
3164 for (
const IVInc &Inc : Chain) {
3165 if (
TTI.isProfitableLSRChainElement(Inc.UserInst))
3167 if (Inc.IncExpr->isZero())
3173 ++NumConstIncrements;
3177 if (Inc.IncExpr == LastIncExpr)
3178 ++NumReusedIncrements;
3182 LastIncExpr = Inc.IncExpr;
3187 if (NumConstIncrements > 1)
3194 cost += NumVarIncrements;
3198 cost -= NumReusedIncrements;
3200 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" Cost: " << cost
3207void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
3208 SmallVectorImpl<ChainUsers> &ChainUsersVec) {
3212 const SCEV *
const OperExpr = SE.
getSCEV(NextIV);
3213 const SCEV *
const OperExprBase =
getExprBase(OperExpr);
3217 unsigned ChainIdx = 0, NChains = IVChainVec.size();
3218 const SCEV *LastIncExpr =
nullptr;
3219 for (; ChainIdx < NChains; ++ChainIdx) {
3220 IVChain &Chain = IVChainVec[ChainIdx];
3238 const SCEV *PrevExpr = SE.
getSCEV(PrevIV);
3239 const SCEV *IncExpr = SE.
getMinusSCEV(OperExpr, PrevExpr);
3243 if (Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
3244 LastIncExpr = IncExpr;
3250 if (ChainIdx == NChains) {
3257 LastIncExpr = OperExpr;
3264 IVChainVec.push_back(IVChain(IVInc(UserInst, IVOper, LastIncExpr),
3266 ChainUsersVec.
resize(NChains);
3267 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Head: (" << *UserInst
3268 <<
") IV=" << *LastIncExpr <<
"\n");
3270 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Inc: (" << *UserInst
3271 <<
") IV+" << *LastIncExpr <<
"\n");
3273 IVChainVec[ChainIdx].add(IVInc(UserInst, IVOper, LastIncExpr));
3275 IVChain &Chain = IVChainVec[ChainIdx];
3277 SmallPtrSet<Instruction*,4> &NearUsers = ChainUsersVec[ChainIdx].NearUsers;
3279 if (!LastIncExpr->
isZero()) {
3280 ChainUsersVec[ChainIdx].FarUsers.insert_range(NearUsers);
3289 for (User *U : IVOper->
users()) {
3295 IVChain::const_iterator IncIter = Chain.Incs.begin();
3296 IVChain::const_iterator IncEnd = Chain.Incs.end();
3297 for( ; IncIter != IncEnd; ++IncIter) {
3298 if (IncIter->UserInst == OtherUse)
3301 if (IncIter != IncEnd)
3306 && IU.isIVUserOrOperand(OtherUse)) {
3309 NearUsers.
insert(OtherUse);
3314 ChainUsersVec[ChainIdx].FarUsers.
erase(UserInst);
3339void LSRInstance::CollectChains() {
3343 SmallVector<BasicBlock *,8> LatchPath;
3346 Rung->
getBlock() != LoopHeader; Rung = Rung->getIDom()) {
3352 for (BasicBlock *BB :
reverse(LatchPath)) {
3353 for (Instruction &
I : *BB) {
3359 if (IU.isEphemeral(&
I))
3369 for (
unsigned ChainIdx = 0, NChains = IVChainVec.size();
3370 ChainIdx < NChains; ++ChainIdx) {
3371 ChainUsersVec[ChainIdx].NearUsers.
erase(&
I);
3374 SmallPtrSet<Instruction*, 4> UniqueOperands;
3377 while (IVOpIter != IVOpEnd) {
3379 if (UniqueOperands.
insert(IVOpInst).second)
3380 ChainInstruction(&
I, IVOpInst, ChainUsersVec);
3381 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3386 for (PHINode &PN :
L->getHeader()->phis()) {
3393 ChainInstruction(&PN, IncV, ChainUsersVec);
3396 unsigned ChainIdx = 0;
3397 for (
unsigned UsersIdx = 0, NChains = IVChainVec.size();
3398 UsersIdx < NChains; ++UsersIdx) {
3400 ChainUsersVec[UsersIdx].FarUsers, SE,
TTI))
3403 if (ChainIdx != UsersIdx)
3404 IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
3405 FinalizeChain(IVChainVec[ChainIdx]);
3408 IVChainVec.resize(ChainIdx);
3411void LSRInstance::FinalizeChain(IVChain &Chain) {
3412 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3413 LLVM_DEBUG(
dbgs() <<
"Final Chain: " << *Chain.Incs[0].UserInst <<
"\n");
3415 for (
const IVInc &Inc : Chain) {
3417 auto UseI =
find(Inc.UserInst->operands(), Inc.IVOperand);
3418 assert(UseI != Inc.UserInst->op_end() &&
"cannot find IV operand");
3419 IVIncSet.insert(UseI);
3427 Immediate IncOffset = Immediate::getZero();
3436 C->getSignificantBits() > 64)
3438 IncOffset = Immediate::getScalable(
C->getSExtValue());
3454void LSRInstance::GenerateIVChain(
const IVChain &Chain,
3455 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
3458 const IVInc &Head = Chain.Incs[0];
3463 Value *IVSrc =
nullptr;
3464 while (IVOpIter != IVOpEnd) {
3475 if (SE.
getSCEV(*IVOpIter) == Head.IncExpr
3476 || SE.
getSCEV(IVSrc) == Head.IncExpr) {
3479 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3481 if (IVOpIter == IVOpEnd) {
3483 LLVM_DEBUG(
dbgs() <<
"Concealed chain head: " << *Head.UserInst <<
"\n");
3486 assert(IVSrc &&
"Failed to find IV chain source");
3491 const SCEV *LeftOverExpr =
nullptr;
3492 const SCEV *Accum = SE.
getZero(IntTy);
3496 for (
const IVInc &Inc : Chain) {
3499 InsertPt =
L->getLoopLatch()->getTerminator();
3503 Value *IVOper = IVSrc;
3504 if (!Inc.IncExpr->isZero()) {
3509 LeftOverExpr = LeftOverExpr ?
3510 SE.
getAddExpr(LeftOverExpr, IncExpr) : IncExpr;
3514 bool FoundBase =
false;
3515 for (
auto [MapScev, MapIVOper] :
reverse(Bases)) {
3516 const SCEV *Remainder = SE.
getMinusSCEV(Accum, MapScev);
3518 if (!Remainder->
isZero()) {
3520 Value *IncV =
Rewriter.expandCodeFor(Remainder, IntTy, InsertPt);
3521 const SCEV *IVOperExpr =
3523 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3532 if (!FoundBase && LeftOverExpr && !LeftOverExpr->
isZero()) {
3535 Value *IncV =
Rewriter.expandCodeFor(LeftOverExpr, IntTy, InsertPt);
3538 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3542 assert(IVTy == IVOper->
getType() &&
"inconsistent IV increment type");
3545 LeftOverExpr =
nullptr;
3549 if (IVTy != OperTy) {
3551 "cannot extend a chained IV");
3553 IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy,
"lsr.chain");
3555 Inc.UserInst->replaceUsesOfWith(Inc.IVOperand, IVOper);
3562 for (PHINode &Phi :
L->getHeader()->phis()) {
3566 Phi.getIncomingValueForBlock(
L->getLoopLatch()));
3569 Value *IVOper = IVSrc;
3571 if (IVTy != PostIncTy) {
3573 IRBuilder<> Builder(
L->getLoopLatch()->getTerminator());
3574 Builder.SetCurrentDebugLocation(PostIncV->
getDebugLoc());
3575 IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy,
"lsr.chain");
3577 Phi.replaceUsesOfWith(PostIncV, IVOper);
3583void LSRInstance::CollectFixupsAndInitialFormulae() {
3584 CondBrInst *ExitBranch =
nullptr;
3585 bool SaveCmp =
TTI.
canSaveCmp(L, &ExitBranch, &SE, &LI, &DT, &AC, &TLI);
3588 SmallPtrSet<const SCEV *, 16> Regs;
3589 DenseSet<const SCEV *> VisitedRegs;
3590 DenseSet<size_t> VisitedLSRUse;
3592 for (
const IVStrideUse &U : IU) {
3597 assert(UseI != UserInst->
op_end() &&
"cannot find IV operand");
3598 if (IVIncSet.count(UseI)) {
3599 LLVM_DEBUG(
dbgs() <<
"Use is in profitable chain: " << **UseI <<
'\n');
3603 LSRUse::KindType
Kind = LSRUse::Basic;
3604 MemAccessTy AccessTy;
3606 Kind = LSRUse::Address;
3610 const SCEV *S = IU.getExpr(U);
3626 if (CI->isEquality()) {
3629 Value *
NV = CI->getOperand(1);
3630 if (NV ==
U.getOperandValToReplace()) {
3631 CI->setOperand(1, CI->getOperand(0));
3632 CI->setOperand(0, NV);
3633 NV = CI->getOperand(1);
3640 (!
NV->getType()->isPointerTy() ||
3647 Kind = LSRUse::ICmpZero;
3649 }
else if (
L->isLoopInvariant(NV) &&
3652 !
NV->getType()->isPointerTy()) {
3663 Kind = LSRUse::ICmpZero;
3670 for (
size_t i = 0, e = Factors.size(); i != e; ++i)
3671 if (Factors[i] != -1)
3672 Factors.insert(-(uint64_t)Factors[i]);
3678 std::pair<size_t, Immediate>
P = getUse(S, Kind, AccessTy);
3679 size_t LUIdx =
P.first;
3681 LSRUse &LU =
Uses[LUIdx];
3684 LSRFixup &LF = LU.getNewFixup();
3685 LF.UserInst = UserInst;
3686 LF.OperandValToReplace =
U.getOperandValToReplace();
3687 LF.PostIncLoops = TmpPostIncLoops;
3689 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3690 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3693 if (!VisitedLSRUse.
count(LUIdx) && !LF.isUseFullyOutsideLoop(L)) {
3695 F.initialMatch(S, L, SE);
3696 BaselineCost.RateFormula(
F, Regs, VisitedRegs, LU,
3697 HardwareLoopProfitable);
3698 VisitedLSRUse.
insert(LUIdx);
3702 if (LU.Formulae.empty()) {
3703 InsertInitialFormula(S, LU, LUIdx);
3704 CountRegisters(LU.Formulae.back(), LUIdx);
3713void LSRInstance::InsertInitialFormula(
const SCEV *S, LSRUse &LU,
3717 LU.RigidFormula =
true;
3720 F.initialMatch(S, L, SE);
3721 bool Inserted = InsertFormula(LU, LUIdx,
F);
3722 assert(Inserted &&
"Initial formula already exists!"); (void)Inserted;
3728LSRInstance::InsertSupplementalFormula(
const SCEV *S,
3729 LSRUse &LU,
size_t LUIdx) {
3731 F.BaseRegs.push_back(S);
3732 F.HasBaseReg =
true;
3733 bool Inserted = InsertFormula(LU, LUIdx,
F);
3734 assert(Inserted &&
"Supplemental formula already exists!"); (void)Inserted;
3738void LSRInstance::CountRegisters(
const Formula &
F,
size_t LUIdx) {
3740 RegUses.countRegister(
F.ScaledReg, LUIdx);
3741 for (
const SCEV *BaseReg :
F.BaseRegs)
3742 RegUses.countRegister(BaseReg, LUIdx);
3747bool LSRInstance::InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F) {
3750 "Formula is illegal");
3752 if (!LU.InsertFormula(
F, *L))
3755 CountRegisters(
F, LUIdx);
3761bool LSRInstance::IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const {
3773LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
3775 SmallPtrSet<const SCEV *, 32> Visited;
3782 while (!Worklist.
empty()) {
3786 if (!Visited.
insert(S).second)
3797 const Value *
V = US->getValue();
3800 if (
L->contains(Inst))
continue;
3804 for (
const Use &U :
V->uses()) {
3814 if (UserInst->
getParent()->getParent() !=
L->getHeader()->getParent())
3836 bool HasIncompatibleEHPTerminatedBlock =
false;
3838 for (
unsigned int I = 0;
I < PhiNode->getNumIncomingValues();
I++) {
3839 if (PhiNode->getIncomingValue(
I) == ExpectedValue) {
3840 if (PhiNode->getIncomingBlock(
I)->getTerminator()->isEHPad()) {
3841 HasIncompatibleEHPTerminatedBlock =
true;
3846 if (HasIncompatibleEHPTerminatedBlock) {
3869 unsigned OtherIdx = !
U.getOperandNo();
3870 Value *OtherOp = ICI->getOperand(OtherIdx);
3880 std::pair<size_t, Immediate>
P =
3881 getUse(S, LSRUse::Basic, MemAccessTy());
3882 size_t LUIdx =
P.first;
3884 LSRUse &LU =
Uses[LUIdx];
3885 LSRFixup &LF = LU.getNewFixup();
3886 LF.UserInst =
const_cast<Instruction *
>(UserInst);
3887 LF.OperandValToReplace =
U;
3889 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3890 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3891 InsertSupplementalFormula(US, LU, LUIdx);
3892 CountRegisters(LU.Formulae.back(),
Uses.size() - 1);
3908 unsigned Depth = 0) {
3915 for (
const SCEV *S :
Add->operands()) {
3922 const SCEV *Start, *Step;
3927 if (Start->isZero())
3936 Remainder =
nullptr;
3938 if (Remainder != Start) {
3960 LSRUse &LU,
const SCEV *S,
const Loop *L,
3962 if (LU.Kind != LSRUse::Address ||
3963 !LU.AccessTy.getType()->isIntOrIntVectorTy())
3969 if (
TTI.isIndexedLoadLegal(
TTI.MIM_PostInc, S->
getType()) ||
3978void LSRInstance::GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
3979 const Formula &
Base,
3980 unsigned Depth,
size_t Idx,
3982 const SCEV *
BaseReg = IsScaledReg ?
Base.ScaledReg :
Base.BaseRegs[Idx];
3990 const SCEV *Remainder =
CollectSubexprs(BaseReg,
nullptr, AddOps, L, SE);
3994 if (AddOps.
size() == 1)
4008 LU.AccessTy, *J,
Base.getNumRegs() > 1))
4013 InnerAddOps.append(std::next(J), std::as_const(AddOps).
end());
4017 if (InnerAddOps.size() == 1 &&
4019 LU.AccessTy, InnerAddOps[0],
Base.getNumRegs() > 1))
4022 const SCEV *InnerSum = SE.
getAddExpr(InnerAddOps);
4027 if (
F.UnfoldedOffset.isNonZero() &&
F.UnfoldedOffset.isScalable())
4036 Immediate::getFixed((uint64_t)
F.UnfoldedOffset.getFixedValue() +
4039 F.ScaledReg =
nullptr;
4042 F.BaseRegs.erase(
F.BaseRegs.begin() + Idx);
4043 }
else if (IsScaledReg)
4044 F.ScaledReg = InnerSum;
4046 F.BaseRegs[Idx] = InnerSum;
4054 Immediate::getFixed((uint64_t)
F.UnfoldedOffset.getFixedValue() +
4057 F.BaseRegs.push_back(*J);
4062 if (InsertFormula(LU, LUIdx,
F))
4069 GenerateReassociations(LU, LUIdx, LU.Formulae.back(),
4075void LSRInstance::GenerateReassociations(LSRUse &LU,
unsigned LUIdx,
4077 assert(
Base.isCanonical(*L) &&
"Input must be in the canonical form");
4082 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4083 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth, i);
4085 if (
Base.Scale == 1)
4086 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth,
4092void LSRInstance::GenerateCombinations(LSRUse &LU,
unsigned LUIdx,
4095 if (
Base.BaseRegs.size() + (
Base.Scale == 1) +
4096 (
Base.UnfoldedOffset.isNonZero()) <=
4104 Formula NewBase =
Base;
4105 NewBase.BaseRegs.clear();
4106 Type *CombinedIntegerType =
nullptr;
4107 for (
const SCEV *BaseReg :
Base.BaseRegs) {
4110 if (!CombinedIntegerType)
4112 Ops.push_back(BaseReg);
4115 NewBase.BaseRegs.push_back(BaseReg);
4119 if (
Ops.size() == 0)
4124 auto GenerateFormula = [&](
const SCEV *Sum) {
4125 Formula
F = NewBase;
4133 F.BaseRegs.push_back(Sum);
4135 (void)InsertFormula(LU, LUIdx,
F);
4139 if (
Ops.size() > 1) {
4146 if (NewBase.UnfoldedOffset.isNonZero() && NewBase.UnfoldedOffset.isFixed()) {
4147 assert(CombinedIntegerType &&
"Missing a type for the unfolded offset");
4149 NewBase.UnfoldedOffset.getFixedValue(),
true));
4150 NewBase.UnfoldedOffset = Immediate::getFixed(0);
4156void LSRInstance::GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
4157 const Formula &
Base,
size_t Idx,
4161 if (
G->isZero() || !GV)
4165 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4170 F.BaseRegs[Idx] =
G;
4171 (void)InsertFormula(LU, LUIdx,
F);
4175void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx,
4178 if (
Base.BaseGV)
return;
4180 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4181 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, i);
4182 if (
Base.Scale == 1)
4183 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, -1,
4188void LSRInstance::GenerateConstantOffsetsImpl(
4189 LSRUse &LU,
unsigned LUIdx,
const Formula &
Base,
4190 const SmallVectorImpl<Immediate> &Worklist,
size_t Idx,
bool IsScaledReg) {
4192 auto GenerateOffset = [&](
const SCEV *
G, Immediate
Offset) {
4194 if (!
Base.BaseOffset.isCompatibleImmediate(
Offset))
4196 F.BaseOffset =
Base.BaseOffset.subUnsigned(
Offset);
4198 if (
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F)) {
4200 const SCEV *NewOffset =
Offset.getSCEV(SE,
G->getType());
4206 F.ScaledReg =
nullptr;
4208 F.deleteBaseReg(
F.BaseRegs[Idx]);
4210 }
else if (IsScaledReg)
4213 F.BaseRegs[Idx] = NewG;
4215 (void)InsertFormula(LU, LUIdx,
F);
4230 const APInt *StepInt;
4235 for (Immediate
Offset : Worklist) {
4237 Offset = Immediate::getFixed(
Offset.getFixedValue() - Step);
4243 for (Immediate
Offset : Worklist)
4250 if (
G->isZero() ||
Imm.isZero() ||
4251 !
Base.BaseOffset.isCompatibleImmediate(Imm))
4254 F.BaseOffset =
F.BaseOffset.addUnsigned(Imm);
4255 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4260 F.BaseRegs[Idx] =
G;
4265 (void)InsertFormula(LU, LUIdx,
F);
4269void LSRInstance::GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx,
4275 if (LU.MaxOffset != LU.MinOffset)
4278 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4279 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, i);
4280 if (
Base.Scale == 1)
4281 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, -1,
4287void LSRInstance::GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx,
4289 if (LU.Kind != LSRUse::ICmpZero)
return;
4297 if (LU.MinOffset != LU.MaxOffset)
return;
4300 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4302 for (
const SCEV *BaseReg :
Base.BaseRegs)
4303 if (
BaseReg->getType()->isPointerTy())
4305 assert(!
Base.BaseGV &&
"ICmpZero use is not legal!");
4308 for (int64_t Factor : Factors) {
4313 if (
Base.BaseOffset.isMin() && Factor == -1)
4316 if (
Base.BaseOffset.isNonZero() &&
Base.BaseOffset.isScalable())
4318 Immediate NewBaseOffset =
Base.BaseOffset.mulUnsigned(Factor);
4319 assert(Factor != 0 &&
"Zero factor not expected!");
4320 if (NewBaseOffset.getFixedValue() / Factor !=
4321 Base.BaseOffset.getFixedValue())
4329 Immediate
Offset = LU.MinOffset;
4330 if (
Offset.isMin() && Factor == -1)
4333 if (
Offset.getFixedValue() / Factor != LU.MinOffset.getFixedValue())
4341 F.BaseOffset = NewBaseOffset;
4348 F.BaseOffset =
F.BaseOffset.addUnsigned(
Offset).subUnsigned(LU.MinOffset);
4350 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4353 for (
size_t i = 0, e =
F.BaseRegs.size(); i != e; ++i) {
4367 if (
F.UnfoldedOffset.isNonZero()) {
4368 if (
F.UnfoldedOffset.isMin() && Factor == -1)
4370 F.UnfoldedOffset =
F.UnfoldedOffset.mulUnsigned(Factor);
4371 if (
F.UnfoldedOffset.getFixedValue() / Factor !=
4372 Base.UnfoldedOffset.getFixedValue())
4376 IntTy,
F.UnfoldedOffset.getFixedValue()))
4381 (void)InsertFormula(LU, LUIdx,
F);
4388void LSRInstance::GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4395 if (
Base.Scale != 0 && !
Base.unscale())
4398 assert(
Base.Scale == 0 &&
"unscale did not did its job!");
4401 for (int64_t Factor : Factors) {
4402 Base.Scale = Factor;
4403 Base.HasBaseReg =
Base.BaseRegs.size() > 1;
4405 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4409 if (LU.Kind == LSRUse::Basic &&
4410 isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
4411 LU.AccessTy,
Base) &&
4412 LU.AllFixupsOutsideLoop)
4413 LU.Kind = LSRUse::Special;
4419 if (LU.Kind == LSRUse::ICmpZero && !
Base.HasBaseReg &&
4420 Base.BaseOffset.isZero() && !
Base.BaseGV)
4423 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i) {
4425 if (AR && (AR->
getLoop() == L || LU.AllFixupsOutsideLoop)) {
4426 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4431 if (
const SCEV *Quotient =
getExactSDiv(AR, FactorS, SE,
true))
4432 if (!Quotient->isZero()) {
4435 F.ScaledReg = Quotient;
4436 F.deleteBaseReg(
F.BaseRegs[i]);
4440 if (
F.Scale == 1 && (
F.BaseRegs.empty() ||
4441 (AR->
getLoop() != L && LU.AllFixupsOutsideLoop)))
4445 if (
F.Scale == 1 && LU.AllFixupsOutsideLoop)
4447 (void)InsertFormula(LU, LUIdx,
F);
4463 const SCEV *Result =
nullptr;
4464 for (
auto &L :
Loops) {
4468 if (!New || (Result && New != Result))
4473 assert(Result &&
"failed to create expression");
4478void LSRInstance::GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4480 if (
Base.BaseGV)
return;
4490 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4493 [](
const SCEV *S) { return S->getType()->isPointerTy(); }))
4497 for (
auto &LF : LU.Fixups)
4498 Loops.push_back(LF.PostIncLoops);
4500 for (
Type *SrcTy : Types) {
4509 const SCEV *NewScaledReg =
4511 if (!NewScaledReg || NewScaledReg->
isZero())
4513 F.ScaledReg = NewScaledReg;
4515 bool HasZeroBaseReg =
false;
4516 for (
const SCEV *&BaseReg :
F.BaseRegs) {
4517 const SCEV *NewBaseReg =
4519 if (!NewBaseReg || NewBaseReg->
isZero()) {
4520 HasZeroBaseReg =
true;
4530 if (!
F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
4534 (void)InsertFormula(LU, LUIdx,
F);
4547 const SCEV *OrigReg;
4549 WorkItem(
size_t LI, Immediate
I,
const SCEV *R)
4550 : LUIdx(LI),
Imm(
I), OrigReg(
R) {}
4552 void print(raw_ostream &OS)
const;
4558#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4559void WorkItem::print(raw_ostream &OS)
const {
4560 OS <<
"in formulae referencing " << *OrigReg <<
" in use " << LUIdx
4561 <<
" , add offset " <<
Imm;
4571void LSRInstance::GenerateCrossUseConstantOffsets() {
4573 using ImmMapTy = std::map<Immediate, const SCEV *, KeyOrderTargetImmediate>;
4575 DenseMap<const SCEV *, ImmMapTy>
Map;
4576 DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
4578 for (
const SCEV *Use : RegUses) {
4582 auto Pair =
Map.try_emplace(
Reg);
4585 Pair.first->second.insert(std::make_pair(Imm, Use));
4586 UsedByIndicesMap[
Reg] |= RegUses.getUsedByIndices(Use);
4593 SmallSet<std::pair<size_t, Immediate>, 32, KeyOrderSizeTAndImmediate>
4595 for (
const SCEV *
Reg : Sequence) {
4596 const ImmMapTy &Imms =
Map.find(
Reg)->second;
4599 if (Imms.size() == 1)
4603 for (
const auto &Entry
4605 <<
' ' <<
Entry.first;
4609 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
4611 const SCEV *OrigReg = J->second;
4613 Immediate JImm = J->first;
4614 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
4617 UsedByIndicesMap[
Reg].
count() == 1) {
4625 Immediate
First = Imms.begin()->first;
4626 Immediate
Last = std::prev(Imms.end())->first;
4627 if (!
First.isCompatibleImmediate(
Last)) {
4634 bool Scalable =
First.isScalable() ||
Last.isScalable();
4635 int64_t FI =
First.getKnownMinValue();
4636 int64_t LI =
Last.getKnownMinValue();
4639 int64_t Avg = (FI & LI) + ((FI ^ LI) >> 1);
4642 Avg = Avg + ((FI ^ LI) & ((uint64_t)Avg >> 63));
4643 ImmMapTy::const_iterator OtherImms[] = {
4644 Imms.begin(), std::prev(Imms.end()),
4645 Imms.lower_bound(Immediate::get(Avg, Scalable))};
4646 for (
const auto &M : OtherImms) {
4647 if (M == J || M == JE)
continue;
4648 if (!JImm.isCompatibleImmediate(
M->first))
4652 Immediate
Imm = JImm.subUnsigned(
M->first);
4653 for (
unsigned LUIdx : UsedByIndices.
set_bits())
4655 if (UniqueItems.
insert(std::make_pair(LUIdx, Imm)).second)
4656 WorkItems.
push_back(WorkItem(LUIdx, Imm, OrigReg));
4663 UsedByIndicesMap.
clear();
4664 UniqueItems.
clear();
4667 for (
const WorkItem &WI : WorkItems) {
4668 size_t LUIdx = WI.LUIdx;
4669 LSRUse &LU =
Uses[LUIdx];
4670 Immediate
Imm = WI.Imm;
4671 const SCEV *OrigReg = WI.OrigReg;
4674 const SCEV *NegImmS =
Imm.getNegativeSCEV(SE, IntTy);
4678 for (
size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
4679 Formula
F = LU.Formulae[
L];
4686 if (
F.ScaledReg == OrigReg) {
4687 if (!
F.BaseOffset.isCompatibleImmediate(Imm))
4689 Immediate
Offset =
F.BaseOffset.addUnsigned(
Imm.mulUnsigned(
F.Scale));
4691 const SCEV *S =
Offset.getNegativeSCEV(SE, IntTy);
4692 if (
F.referencesReg(S))
4695 NewF.BaseOffset =
Offset;
4696 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4699 NewF.ScaledReg = SE.
getAddExpr(NegImmS, NewF.ScaledReg);
4708 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4710 if (
C->getValue()->isNegative() !=
4711 (NewF.BaseOffset.isLessThanZero()) &&
4712 (
C->getAPInt().abs() * APInt(
BitWidth,
F.Scale))
4713 .ule(std::abs(NewF.BaseOffset.getFixedValue())))
4718 NewF.canonicalize(*this->L);
4719 (void)InsertFormula(LU, LUIdx, NewF);
4722 for (
size_t N = 0, NE =
F.BaseRegs.size();
N != NE; ++
N) {
4724 if (BaseReg != OrigReg)
4727 if (!NewF.BaseOffset.isCompatibleImmediate(Imm) ||
4728 !NewF.UnfoldedOffset.isCompatibleImmediate(Imm) ||
4729 !NewF.BaseOffset.isCompatibleImmediate(NewF.UnfoldedOffset))
4731 NewF.BaseOffset = NewF.BaseOffset.addUnsigned(Imm);
4733 LU.Kind, LU.AccessTy, NewF)) {
4737 Immediate NewUnfoldedOffset = NewF.UnfoldedOffset.addUnsigned(Imm);
4741 NewF.UnfoldedOffset = NewUnfoldedOffset;
4743 NewF.BaseRegs[
N] = SE.
getAddExpr(NegImmS, BaseReg);
4748 for (
const SCEV *NewReg : NewF.BaseRegs)
4750 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4752 if ((
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4754 .slt(std::abs(NewF.BaseOffset.getFixedValue())) &&
4755 (
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4758 NewF.BaseOffset.getFixedValue()))
4763 NewF.canonicalize(*this->L);
4764 (void)InsertFormula(LU, LUIdx, NewF);
4775LSRInstance::GenerateAllReuseFormulae() {
4778 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4779 LSRUse &LU =
Uses[LUIdx];
4780 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4781 GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
4782 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4783 GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
4785 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4786 LSRUse &LU =
Uses[LUIdx];
4787 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4788 GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
4789 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4790 GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
4791 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4792 GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
4793 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4794 GenerateScales(LU, LUIdx, LU.Formulae[i]);
4796 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4797 LSRUse &LU =
Uses[LUIdx];
4798 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4799 GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
4802 GenerateCrossUseConstantOffsets();
4805 "After generating reuse formulae:\n";
4806 print_uses(
dbgs()));
4811void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
4812 DenseSet<const SCEV *> VisitedRegs;
4813 SmallPtrSet<const SCEV *, 16> Regs;
4814 SmallPtrSet<const SCEV *, 16> LoserRegs;
4816 bool ChangedFormulae =
false;
4821 using BestFormulaeTy = DenseMap<SmallVector<const SCEV *, 4>,
size_t>;
4823 BestFormulaeTy BestFormulae;
4825 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4826 LSRUse &LU =
Uses[LUIdx];
4831 for (
size_t FIdx = 0, NumForms = LU.Formulae.size();
4832 FIdx != NumForms; ++FIdx) {
4833 Formula &
F = LU.Formulae[FIdx];
4844 CostF.RateFormula(
F, Regs, VisitedRegs, LU, HardwareLoopProfitable,
4846 if (CostF.isLoser()) {
4858 for (
const SCEV *
Reg :
F.BaseRegs) {
4859 if (RegUses.isRegUsedByUsesOtherThan(
Reg, LUIdx))
4863 RegUses.isRegUsedByUsesOtherThan(
F.ScaledReg, LUIdx))
4864 Key.push_back(
F.ScaledReg);
4869 std::pair<BestFormulaeTy::const_iterator, bool>
P =
4870 BestFormulae.insert(std::make_pair(
Key, FIdx));
4874 Formula &Best = LU.Formulae[
P.first->second];
4876 Cost CostBest(L, SE,
TTI, AMK);
4878 CostBest.RateFormula(Best, Regs, VisitedRegs, LU,
4879 HardwareLoopProfitable);
4880 if (CostF.isLess(CostBest))
4884 " in favor of formula ";
4885 Best.print(
dbgs());
dbgs() <<
'\n');
4888 ChangedFormulae =
true;
4890 LU.DeleteFormula(
F);
4898 LU.RecomputeRegs(LUIdx, RegUses);
4901 BestFormulae.clear();
4906 "After filtering out undesirable candidates:\n";
4914size_t LSRInstance::EstimateSearchSpaceComplexity()
const {
4916 for (
const LSRUse &LU :
Uses) {
4917 size_t FSize = LU.Formulae.size();
4932void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
4936 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by eliminating formulae "
4937 "which use a superset of registers used by other "
4940 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4941 LSRUse &LU =
Uses[LUIdx];
4943 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
4944 Formula &
F = LU.Formulae[i];
4945 if (
F.BaseOffset.isNonZero() &&
F.BaseOffset.isScalable())
4951 I =
F.BaseRegs.begin(),
E =
F.BaseRegs.end();
I !=
E; ++
I) {
4957 Immediate::getFixed(NewF.BaseOffset.getFixedValue() +
4958 (uint64_t)
C->getValue()->getSExtValue());
4959 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4960 (
I -
F.BaseRegs.begin()));
4961 if (LU.HasFormulaWithSameRegs(NewF)) {
4964 LU.DeleteFormula(
F);
4975 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4976 (
I -
F.BaseRegs.begin()));
4977 if (LU.HasFormulaWithSameRegs(NewF)) {
4980 LU.DeleteFormula(
F);
4991 LU.RecomputeRegs(LUIdx, RegUses);
5000void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
5005 dbgs() <<
"The search space is too complex.\n"
5006 "Narrowing the search space by assuming that uses separated "
5007 "by a constant offset will use the same registers.\n");
5011 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5012 LSRUse &LU =
Uses[LUIdx];
5013 for (
const Formula &
F : LU.Formulae) {
5014 if (
F.BaseOffset.isZero() || (
F.Scale != 0 &&
F.Scale != 1))
5016 assert((LU.Kind == LSRUse::Address || LU.Kind == LSRUse::ICmpZero) &&
5017 "Only address and cmp uses expected to have nonzero BaseOffset");
5019 LSRUse *LUThatHas = FindUseWithSimilarFormula(
F, LU);
5023 if (!reconcileNewOffset(*LUThatHas,
F.BaseOffset,
false,
5024 LU.Kind, LU.AccessTy))
5029 LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
5030 LUThatHas->AllFixupsUnconditional &= LU.AllFixupsUnconditional;
5033 for (LSRFixup &
Fixup : LU.Fixups) {
5034 Fixup.Offset +=
F.BaseOffset;
5035 LUThatHas->pushFixup(
Fixup);
5040 Type *FixupType = LUThatHas->Fixups[0].OperandValToReplace->getType();
5041 for (LSRFixup &
Fixup : LUThatHas->Fixups)
5042 assert(
Fixup.OperandValToReplace->getType() == FixupType &&
5043 "Expected all fixups to have the same type");
5048 for (
size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
5049 Formula &
F = LUThatHas->Formulae[i];
5050 if (!
isLegalUse(
TTI, LUThatHas->MinOffset, LUThatHas->MaxOffset,
5051 LUThatHas->Kind, LUThatHas->AccessTy,
F)) {
5053 LUThatHas->DeleteFormula(
F);
5061 LUThatHas->RecomputeRegs(LUThatHas - &
Uses.front(), RegUses);
5064 DeleteUse(LU, LUIdx);
5077void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
5081 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by re-filtering out "
5082 "undesirable dedicated registers.\n");
5084 FilterOutUndesirableDedicatedRegisters();
5099void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
5104 dbgs() <<
"The search space is too complex.\n"
5105 "Narrowing the search space by choosing the best Formula "
5106 "from the Formulae with the same Scale and ScaledReg.\n");
5109 using BestFormulaeTy = DenseMap<std::pair<const SCEV *, int64_t>,
size_t>;
5111 BestFormulaeTy BestFormulae;
5113 bool ChangedFormulae =
false;
5115 DenseSet<const SCEV *> VisitedRegs;
5116 SmallPtrSet<const SCEV *, 16> Regs;
5118 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5119 LSRUse &LU =
Uses[LUIdx];
5124 auto IsBetterThan = [&](Formula &FA, Formula &FB) {
5129 size_t FARegNum = 0;
5130 for (
const SCEV *
Reg : FA.BaseRegs) {
5131 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5132 FARegNum += (NumUses - UsedByIndices.
count() + 1);
5134 size_t FBRegNum = 0;
5135 for (
const SCEV *
Reg : FB.BaseRegs) {
5136 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5137 FBRegNum += (NumUses - UsedByIndices.
count() + 1);
5139 if (FARegNum != FBRegNum)
5140 return FARegNum < FBRegNum;
5147 CostFA.RateFormula(FA, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5149 CostFB.RateFormula(FB, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5150 return CostFA.isLess(CostFB);
5154 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5156 Formula &
F = LU.Formulae[FIdx];
5159 auto P = BestFormulae.insert({{
F.ScaledReg,
F.Scale}, FIdx});
5163 Formula &Best = LU.Formulae[
P.first->second];
5164 if (IsBetterThan(
F, Best))
5168 " in favor of formula ";
5169 Best.print(
dbgs());
dbgs() <<
'\n');
5171 ChangedFormulae =
true;
5173 LU.DeleteFormula(
F);
5179 LU.RecomputeRegs(LUIdx, RegUses);
5182 BestFormulae.clear();
5187 "After filtering out undesirable candidates:\n";
5194void LSRInstance::NarrowSearchSpaceByFilterPostInc() {
5201 "Narrowing the search space by choosing the lowest "
5202 "register Formula for PostInc Uses.\n");
5204 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5205 LSRUse &LU =
Uses[LUIdx];
5207 if (LU.Kind != LSRUse::Address)
5213 size_t MinRegs = std::numeric_limits<size_t>::max();
5214 for (
const Formula &
F : LU.Formulae)
5215 MinRegs = std::min(
F.getNumRegs(), MinRegs);
5218 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5220 Formula &
F = LU.Formulae[FIdx];
5221 if (
F.getNumRegs() > MinRegs) {
5224 LU.DeleteFormula(
F);
5231 LU.RecomputeRegs(LUIdx, RegUses);
5240void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
5245 dbgs() <<
"The search space is too complex.\n"
5246 "Narrowing the search space by merging uses with fixups "
5247 "entirely outside the loop with uses inside the loop.\n");
5249 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5250 LSRUse &LU =
Uses[LUIdx];
5253 if (!LU.AllFixupsOutsideLoop || LU.Formulae.empty() ||
5254 LU.Kind == LSRUse::ICmpZero)
5261 LSRUse *LUToMergeWith =
nullptr;
5262 const Formula &ThisF = LU.Formulae[0];
5263 for (LSRUse &OtherLU :
Uses) {
5265 if (OtherLU.AllFixupsOutsideLoop)
5269 if (OtherLU.Kind == LSRUse::ICmpZero)
5272 if (OtherLU.Formulae.empty())
5275 if (
any_of(OtherLU.Formulae, [&](
const Formula &
F) {
5276 return !isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, OtherLU.Kind,
5277 OtherLU.AccessTy, F);
5284 const Formula &OtherF = OtherLU.Formulae[0];
5285 if (ThisF.BaseRegs == OtherF.BaseRegs &&
5286 ThisF.ScaledReg == OtherF.ScaledReg &&
5287 ThisF.BaseGV == OtherF.BaseGV && ThisF.Scale == OtherF.Scale &&
5288 ThisF.UnfoldedOffset == OtherF.UnfoldedOffset &&
5289 ThisF.BaseOffset == OtherF.BaseOffset) {
5290 LUToMergeWith = &OtherLU;
5301 for (LSRFixup &
Fixup : LU.Fixups) {
5302 LUToMergeWith->pushFixup(
Fixup);
5306 DeleteUse(LU, LUIdx);
5356void LSRInstance::NarrowSearchSpaceByDeletingCostlyFormulas() {
5365 SmallPtrSet<const SCEV *, 4> UniqRegs;
5369 DenseMap <const SCEV *, float> RegNumMap;
5370 for (
const SCEV *
Reg : RegUses) {
5374 for (
const LSRUse &LU :
Uses) {
5375 if (!LU.Regs.count(
Reg))
5377 float P = LU.getNotSelectedProbability(
Reg);
5383 RegNumMap.
insert(std::make_pair(
Reg, PNotSel));
5387 dbgs() <<
"Narrowing the search space by deleting costly formulas\n");
5390 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5391 LSRUse &LU =
Uses[LUIdx];
5393 if (LU.Formulae.size() < 2)
5398 float FMinRegNum = LU.Formulae[0].getNumRegs();
5399 float FMinARegNum = LU.Formulae[0].getNumRegs();
5401 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5402 Formula &
F = LU.Formulae[i];
5405 for (
const SCEV *BaseReg :
F.BaseRegs) {
5406 if (UniqRegs.
count(BaseReg))
5408 FRegNum += RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5411 RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5413 if (
const SCEV *ScaledReg =
F.ScaledReg) {
5414 if (!UniqRegs.
count(ScaledReg)) {
5416 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5419 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5422 if (FMinRegNum > FRegNum ||
5423 (FMinRegNum == FRegNum && FMinARegNum > FARegNum)) {
5424 FMinRegNum = FRegNum;
5425 FMinARegNum = FARegNum;
5430 dbgs() <<
" with min reg num " << FMinRegNum <<
'\n');
5432 std::swap(LU.Formulae[MinIdx], LU.Formulae[0]);
5433 while (LU.Formulae.size() != 1) {
5436 LU.Formulae.pop_back();
5438 LU.RecomputeRegs(LUIdx, RegUses);
5439 assert(LU.Formulae.size() == 1 &&
"Should be exactly 1 min regs formula");
5440 Formula &
F = LU.Formulae[0];
5456 MemAccessTy AccessType) {
5466 return TTI.isLegalAddressingMode(
5467 AccessType.MemTy,
nullptr,
5468 Diff->getSExtValue(),
5469 true, 0, AccessType.AddrSpace) &&
5470 !
TTI.isLegalAddressingMode(
5471 AccessType.MemTy,
nullptr,
5472 -Diff->getSExtValue(),
5473 true, 0, AccessType.AddrSpace);
5479void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
5482 SmallPtrSet<const SCEV *, 4> Taken;
5490 const SCEV *Best =
nullptr;
5491 unsigned BestNum = 0;
5492 for (
const SCEV *
Reg : RegUses) {
5497 BestNum = RegUses.getUsedByIndices(
Reg).count();
5499 unsigned Count = RegUses.getUsedByIndices(
Reg).count();
5500 if (
Count > BestNum) {
5508 if (
Count == BestNum) {
5509 int LUIdx = RegUses.getUsedByIndices(
Reg).find_first();
5510 if (LUIdx >= 0 &&
Uses[LUIdx].Kind == LSRUse::Address &&
5512 Uses[LUIdx].AccessTy)) {
5519 assert(Best &&
"Failed to find best LSRUse candidate");
5521 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by assuming " << *Best
5522 <<
" will yield profitable reuse.\n");
5527 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5528 LSRUse &LU =
Uses[LUIdx];
5529 if (!LU.Regs.count(Best))
continue;
5532 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5533 Formula &
F = LU.Formulae[i];
5534 if (!
F.referencesReg(Best)) {
5536 LU.DeleteFormula(
F);
5540 assert(e != 0 &&
"Use has no formulae left! Is Regs inconsistent?");
5546 LU.RecomputeRegs(LUIdx, RegUses);
5557void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
5558 NarrowSearchSpaceByDetectingSupersets();
5559 NarrowSearchSpaceByCollapsingUnrolledCode();
5560 NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
5562 NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
5563 NarrowSearchSpaceByFilterPostInc();
5564 NarrowSearchSpaceByMergingUsesOutsideLoop();
5566 NarrowSearchSpaceByDeletingCostlyFormulas();
5568 NarrowSearchSpaceByPickingWinnerRegs();
5572void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
5574 SmallVectorImpl<const Formula *> &Workspace,
5575 const Cost &CurCost,
5576 const SmallPtrSet<const SCEV *, 16> &CurRegs,
5577 DenseSet<const SCEV *> &VisitedRegs)
const {
5588 const LSRUse &LU =
Uses[Workspace.
size()];
5594 SmallSetVector<const SCEV *, 4> ReqRegs;
5595 for (
const SCEV *S : CurRegs)
5596 if (LU.Regs.count(S))
5599 SmallPtrSet<const SCEV *, 16> NewRegs;
5600 Cost NewCost(L, SE,
TTI, AMK);
5601 for (
const Formula &
F : LU.Formulae) {
5609 int NumReqRegsToFind = std::min(
F.getNumRegs(), ReqRegs.
size());
5610 for (
const SCEV *
Reg : ReqRegs) {
5611 if ((
F.ScaledReg &&
F.ScaledReg ==
Reg) ||
5614 if (NumReqRegsToFind == 0)
5618 if (NumReqRegsToFind != 0) {
5629 NewCost.RateFormula(
F, NewRegs, VisitedRegs, LU, HardwareLoopProfitable);
5630 if (NewCost.isLess(SolutionCost)) {
5632 if (Workspace.
size() !=
Uses.size()) {
5633 SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
5634 NewRegs, VisitedRegs);
5635 if (
F.getNumRegs() == 1 && Workspace.
size() == 1)
5636 VisitedRegs.
insert(
F.ScaledReg ?
F.ScaledReg :
F.BaseRegs[0]);
5639 dbgs() <<
".\nRegs:\n";
5640 for (
const SCEV *S : NewRegs)
dbgs()
5641 <<
"- " << *S <<
"\n";
5644 SolutionCost = NewCost;
5645 Solution = Workspace;
5654void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution)
const {
5656 Cost SolutionCost(L, SE,
TTI, AMK);
5657 SolutionCost.Lose();
5658 Cost CurCost(L, SE,
TTI, AMK);
5659 SmallPtrSet<const SCEV *, 16> CurRegs;
5660 DenseSet<const SCEV *> VisitedRegs;
5664 SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
5665 CurRegs, VisitedRegs);
5666 if (Solution.
empty()) {
5673 "The chosen solution requires ";
5674 SolutionCost.print(
dbgs());
dbgs() <<
":\n";
5675 for (
size_t i = 0, e =
Uses.size(); i != e; ++i) {
5680 Solution[i]->print(
dbgs());
5686 const bool EnableDropUnprofitableSolution = [&] {
5688 case cl::boolOrDefault::BOU_TRUE:
5690 case cl::boolOrDefault::BOU_FALSE:
5692 case cl::boolOrDefault::BOU_UNSET:
5698 if (BaselineCost.isLess(SolutionCost)) {
5699 if (!EnableDropUnprofitableSolution)
5701 dbgs() <<
"Baseline is more profitable than chosen solution, "
5702 "add option 'lsr-drop-solution' to drop LSR solution.\n");
5705 "solution, dropping LSR solution.\n";);
5716 const SmallVectorImpl<Instruction *> &Inputs)
5720 bool AllDominate =
true;
5727 for (Instruction *Inst : Inputs) {
5728 if (Inst == Tentative || !DT.
dominates(Inst, Tentative)) {
5729 AllDominate =
false;
5734 if (Tentative->
getParent() == Inst->getParent() &&
5735 (!BetterPos || !DT.
dominates(Inst, BetterPos)))
5745 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
5746 unsigned IPLoopDepth = IPLoop ? IPLoop->
getLoopDepth() : 0;
5750 if (!Rung)
return IP;
5751 Rung = Rung->getIDom();
5752 if (!Rung)
return IP;
5753 IDom = Rung->getBlock();
5756 const Loop *IDomLoop = LI.getLoopFor(IDom);
5757 unsigned IDomDepth = IDomLoop ? IDomLoop->
getLoopDepth() : 0;
5758 if (IDomDepth <= IPLoopDepth &&
5759 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
5776 SmallVector<Instruction *, 4> Inputs;
5779 if (LU.Kind == LSRUse::ICmpZero)
5780 if (Instruction *
I =
5783 if (LF.PostIncLoops.
count(L)) {
5784 if (LF.isUseFullyOutsideLoop(L))
5785 Inputs.
push_back(
L->getLoopLatch()->getTerminator());
5791 for (
const Loop *PIL : LF.PostIncLoops) {
5792 if (PIL == L)
continue;
5797 if (!ExitingBlocks.
empty()) {
5799 for (
unsigned i = 1, e = ExitingBlocks.
size(); i != e; ++i)
5806 "Insertion point must be a normal instruction");
5816 while (IP->isEHPad()) ++IP;
5821 while (
Rewriter.isInsertedInstruction(&*IP) && IP != LowestIP)
5829Value *LSRInstance::Expand(
const LSRUse &LU,
const LSRFixup &LF,
5831 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const {
5832 if (LU.RigidFormula)
5833 return LF.OperandValToReplace;
5837 IP = AdjustInsertPositionForExpand(IP, LF, LU);
5842 Rewriter.setPostInc(LF.PostIncLoops);
5847 Type *Ty =
F.getType();
5860 if (LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy()) {
5869 for (
const SCEV *
Reg :
F.BaseRegs) {
5870 assert(!
Reg->isZero() &&
"Zero allocated in a base register!");
5878 Value *ICmpScaledV =
nullptr;
5880 const SCEV *ScaledS =
F.ScaledReg;
5886 if (LU.Kind == LSRUse::ICmpZero) {
5896 "The only scale supported by ICmpZero uses is -1!");
5897 ICmpScaledV =
Rewriter.expandCodeFor(ScaledS,
nullptr);
5905 if (!
Ops.empty() && LU.Kind == LSRUse::Address &&
5915 Ops.push_back(ScaledS);
5941 assert(
F.BaseOffset.isCompatibleImmediate(LF.Offset) &&
5942 "Expanding mismatched offsets\n");
5944 Immediate
Offset =
F.BaseOffset.addUnsigned(LF.Offset);
5945 if (
Offset.isNonZero()) {
5946 if (LU.Kind == LSRUse::ICmpZero) {
5953 IntTy, -(uint64_t)
Offset.getFixedValue(),
true);
5962 Ops.push_back(
Offset.getUnknownSCEV(SE, IntTy));
5967 Immediate UnfoldedOffset =
F.UnfoldedOffset;
5968 if (UnfoldedOffset.isNonZero()) {
5970 Ops.push_back(UnfoldedOffset.getUnknownSCEV(SE, IntTy));
5974 const SCEV *FullS =
Ops.empty() ?
5985 if (LU.Kind == LSRUse::ICmpZero) {
5989 assert(!
F.BaseGV &&
"ICmp does not support folding a global value and "
5990 "a scale at the same time!");
5991 if (
F.Scale == -1) {
5992 if (ICmpScaledV->
getType() != OpTy) {
6002 assert((
F.Scale == 0 ||
F.Scale == 1) &&
6003 "ICmp does not support folding a global value and "
6004 "a scale at the same time!");
6008 -(uint64_t)
Offset.getFixedValue(),
6010 if (
C->getType() != OpTy) {
6014 assert(
C &&
"Cast of ConstantInt should have folded");
6027void LSRInstance::RewriteForPHI(PHINode *PN,
const LSRUse &LU,
6028 const LSRFixup &LF,
const Formula &
F,
6029 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6030 DenseMap<BasicBlock *, Value *>
Inserted;
6034 bool needUpdateFixups =
false;
6045 Loop *PNLoop = LI.getLoopFor(Parent);
6046 if (!PNLoop || Parent != PNLoop->
getHeader()) {
6050 CriticalEdgeSplittingOptions SplitOptions(&DT, &LI, MSSAU);
6052 SplitOptions.setMergeIdenticalEdges().setKeepOneInputPHIs();
6053 if (ShouldPreserveLCSSA)
6054 SplitOptions = SplitOptions.setPreserveLCSSA();
6058 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
6069 if (
L->contains(BB) && !
L->contains(PN))
6077 needUpdateFixups =
true;
6082 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> Pair =
6095 LF.OperandValToReplace->
getType(),
"tmp",
6102 if (
L->contains(
I) && !
L->contains(BB))
6103 InsertedNonLCSSAInsts.insert(
I);
6106 Pair.first->second = FullV;
6113 if (needUpdateFixups) {
6114 for (LSRUse &LU :
Uses)
6115 for (LSRFixup &
Fixup : LU.Fixups)
6119 if (
Fixup.UserInst == PN) {
6122 bool foundInOriginalPHI =
false;
6124 if (val ==
Fixup.OperandValToReplace) {
6125 foundInOriginalPHI =
true;
6130 if (foundInOriginalPHI)
6141 if (val ==
Fixup.OperandValToReplace)
6142 Fixup.UserInst = NewPN;
6152void LSRInstance::Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
6154 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6158 RewriteForPHI(PN, LU, LF,
F, DeadInsts);
6166 if (FullV->
getType() != OpTy &&
6167 !(LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy())) {
6179 if (LU.Kind == LSRUse::ICmpZero)
6195 const LSRFixup &
Fixup,
const LSRUse &LU,
6199 if (LU.Kind != LSRUse::Address)
6200 return IVIncInsertPos;
6204 Type *Ty =
I->getType();
6207 return IVIncInsertPos;
6214 return IVIncInsertPos;
6221void LSRInstance::ImplementSolution(
6222 const SmallVectorImpl<const Formula *> &Solution) {
6228 for (
const IVChain &Chain : IVChainVec) {
6234 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx)
6235 for (
const LSRFixup &
Fixup :
Uses[LUIdx].Fixups) {
6238 Rewriter.setIVIncInsertPos(L, InsertPos);
6239 Rewrite(
Uses[LUIdx],
Fixup, *Solution[LUIdx], DeadInsts);
6243 auto InsertedInsts = InsertedNonLCSSAInsts.takeVector();
6246 for (
const IVChain &Chain : IVChainVec) {
6247 GenerateIVChain(Chain, DeadInsts);
6251 for (
const WeakVH &
IV :
Rewriter.getInsertedIVs())
6269 for (PHINode &PN :
L->getHeader()->phis()) {
6270 BinaryOperator *BO =
nullptr;
6276 case Instruction::Sub:
6281 case Instruction::Add:
6298 [&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
6307LSRInstance::LSRInstance(Loop *L, IVUsers &IU, ScalarEvolution &SE,
6308 DominatorTree &DT, LoopInfo &LI,
6309 const TargetTransformInfo &
TTI, AssumptionCache &AC,
6310 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
6312 : IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI),
TTI(
TTI),
L(
L),
6315 :
TTI.getPreferredAddressingMode(
L, &SE)),
6316 Rewriter(SE,
"lsr", PreserveLCSSA), ShouldPreserveLCSSA(PreserveLCSSA),
6317 BaselineCost(
L, SE,
TTI, AMK) {
6319 if (!
L->isLoopSimplifyForm())
6327 unsigned NumUsers = 0;
6331 LLVM_DEBUG(
dbgs() <<
"LSR skipping loop, too many IV Users in " << U
6339 auto FirstNonPHI = PN->
getParent()->getFirstNonPHIIt();
6349 L->getHeader()->printAsOperand(
dbgs(),
false);
6355 HardwareLoopProfitable =
6356 TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo);
6360#if LLVM_ENABLE_ABI_BREAKING_CHECKS
6363 Rewriter.disableCanonicalMode();
6364 Rewriter.enableLSRMode();
6368 OptimizeLoopTermCond();
6371 if (IU.empty())
return;
6374 if (!
L->isInnermost()) {
6387 CollectInterestingTypesAndFactors();
6388 CollectFixupsAndInitialFormulae();
6389 CollectLoopInvariantFixupsAndFormulae();
6395 print_uses(
dbgs()));
6397 BaselineCost.print(
dbgs());
dbgs() <<
"\n");
6401 GenerateAllReuseFormulae();
6403 FilterOutUndesirableDedicatedRegisters();
6404 NarrowSearchSpaceUsingHeuristics();
6414 if (Solution.
empty())
6419 for (
const LSRUse &LU :
Uses) {
6420 for (
const Formula &
F : LU.Formulae)
6422 F) &&
"Illegal formula generated!");
6427 ImplementSolution(Solution);
6430#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
6431void LSRInstance::print_factors_and_types(
raw_ostream &OS)
const {
6432 if (Factors.empty() &&
Types.empty())
return;
6434 OS <<
"LSR has identified the following interesting factors and types: ";
6437 for (int64_t Factor : Factors)
6438 OS <<
LS <<
'*' << Factor;
6440 for (
Type *Ty : Types)
6441 OS <<
LS <<
'(' << *Ty <<
')';
6445void LSRInstance::print_fixups(raw_ostream &OS)
const {
6446 OS <<
"LSR is examining the following fixup sites:\n";
6447 for (
const LSRUse &LU :
Uses)
6448 for (
const LSRFixup &LF : LU.Fixups) {
6455void LSRInstance::print_uses(raw_ostream &OS)
const {
6456 OS <<
"LSR is examining the following uses:\n";
6457 for (
const LSRUse &LU :
Uses) {
6461 for (
const Formula &
F : LU.Formulae) {
6469void LSRInstance::print(raw_ostream &OS)
const {
6470 print_factors_and_types(OS);
6482class LoopStrengthReduce :
public LoopPass {
6486 LoopStrengthReduce();
6489 bool runOnLoop(Loop *L, LPPassManager &LPM)
override;
6490 void getAnalysisUsage(AnalysisUsage &AU)
const override;
6495LoopStrengthReduce::LoopStrengthReduce() : LoopPass(
ID) {
6499void LoopStrengthReduce::getAnalysisUsage(
AnalysisUsage &AU)
const {
6526ToDwarfOpIter(SmallVectorImpl<uint64_t> &Expr) {
6527 llvm::DIExpression::expr_op_iterator Begin =
6528 llvm::DIExpression::expr_op_iterator(Expr.
begin());
6529 llvm::DIExpression::expr_op_iterator End =
6530 llvm::DIExpression::expr_op_iterator(Expr.
end());
6531 return {Begin, End};
6534struct SCEVDbgValueBuilder {
6535 SCEVDbgValueBuilder() =
default;
6536 SCEVDbgValueBuilder(
const SCEVDbgValueBuilder &
Base) { clone(
Base); }
6538 void clone(
const SCEVDbgValueBuilder &
Base) {
6539 LocationOps =
Base.LocationOps;
6544 LocationOps.
clear();
6551 SmallVector<Value *, 2> LocationOps;
6554 void pushUInt(uint64_t Operand) { Expr.
push_back(Operand); }
6561 unsigned ArgIndex = 0;
6562 if (It != LocationOps.
end()) {
6563 ArgIndex = std::distance(LocationOps.
begin(), It);
6565 ArgIndex = LocationOps.
size();
6571 void pushValue(
const SCEVUnknown *U) {
6576 bool pushConst(
const SCEVConstant *
C) {
6577 if (
C->getAPInt().getSignificantBits() > 64)
6579 Expr.
push_back(llvm::dwarf::DW_OP_consts);
6580 Expr.
push_back(
C->getAPInt().getSExtValue());
6587 return ToDwarfOpIter(Expr);
6592 bool pushArithmeticExpr(
const llvm::SCEVCommutativeExpr *CommExpr,
6595 "Expected arithmetic SCEV type");
6597 unsigned EmitOperator = 0;
6598 for (
const auto &
Op : CommExpr->
operands()) {
6601 if (EmitOperator >= 1)
6602 pushOperator(DwarfOp);
6609 bool pushCast(
const llvm::SCEVCastExpr *
C,
bool IsSigned) {
6610 const llvm::SCEV *Inner =
C->getOperand(0);
6611 const llvm::Type *
Type =
C->getType();
6612 uint64_t ToWidth =
Type->getIntegerBitWidth();
6613 bool Success = pushSCEV(Inner);
6615 IsSigned ? llvm::dwarf::DW_ATE_signed
6616 : llvm::dwarf::DW_ATE_unsigned};
6617 for (
const auto &
Op : CastOps)
6623 bool pushSCEV(
const llvm::SCEV *S) {
6626 Success &= pushConst(StartInt);
6631 pushLocation(
U->getValue());
6634 Success &= pushArithmeticExpr(MulRec, llvm::dwarf::DW_OP_mul);
6637 Success &= pushSCEV(UDiv->getLHS());
6638 Success &= pushSCEV(UDiv->getRHS());
6639 pushOperator(llvm::dwarf::DW_OP_div);
6646 "Unexpected cast type in SCEV.");
6650 Success &= pushArithmeticExpr(AddExpr, llvm::dwarf::DW_OP_plus);
6665 bool isIdentityFunction(uint64_t
Op,
const SCEV *S) {
6667 if (
C->getAPInt().getSignificantBits() > 64)
6669 int64_t
I =
C->getAPInt().getSExtValue();
6671 case llvm::dwarf::DW_OP_plus:
6672 case llvm::dwarf::DW_OP_minus:
6674 case llvm::dwarf::DW_OP_mul:
6675 case llvm::dwarf::DW_OP_div:
6688 bool SCEVToValueExpr(
const llvm::SCEVAddRecExpr &SAR, ScalarEvolution &SE) {
6694 if (!isIdentityFunction(llvm::dwarf::DW_OP_mul, Stride)) {
6695 if (!pushSCEV(Stride))
6697 pushOperator(llvm::dwarf::DW_OP_mul);
6699 if (!isIdentityFunction(llvm::dwarf::DW_OP_plus, Start)) {
6700 if (!pushSCEV(Start))
6702 pushOperator(llvm::dwarf::DW_OP_plus);
6708 void createOffsetExpr(int64_t
Offset,
Value *OffsetValue) {
6709 pushLocation(OffsetValue);
6712 dbgs() <<
"scev-salvage: Generated IV offset expression. Offset: "
6713 << std::to_string(
Offset) <<
"\n");
6719 bool createIterCountExpr(
const SCEV *S,
6720 const SCEVDbgValueBuilder &IterationCount,
6721 ScalarEvolution &SE) {
6730 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Location to salvage SCEV: " << *S
6734 if (!Rec->isAffine())
6742 clone(IterationCount);
6743 if (!SCEVToValueExpr(*Rec, SE))
6754 bool SCEVToIterCountExpr(
const llvm::SCEVAddRecExpr &SAR,
6755 ScalarEvolution &SE) {
6761 if (!isIdentityFunction(llvm::dwarf::DW_OP_minus, Start)) {
6762 if (!pushSCEV(Start))
6764 pushOperator(llvm::dwarf::DW_OP_minus);
6766 if (!isIdentityFunction(llvm::dwarf::DW_OP_div, Stride)) {
6767 if (!pushSCEV(Stride))
6769 pushOperator(llvm::dwarf::DW_OP_div);
6777 void appendToVectors(SmallVectorImpl<uint64_t> &DestExpr,
6778 SmallVectorImpl<Value *> &DestLocations) {
6780 "Expected the locations vector to contain the IV");
6785 "Expected the location ops to contain the IV.");
6789 for (
const auto &
Op : LocationOps) {
6790 auto It =
find(DestLocations,
Op);
6791 if (It != DestLocations.
end()) {
6793 DestIndexMap.
push_back(std::distance(DestLocations.
begin(), It));
6801 for (
const auto &
Op : expr_ops()) {
6803 Op.appendToVector(DestExpr);
6810 uint64_t NewIndex = DestIndexMap[
Op.getArg(0)];
6818struct DVIRecoveryRec {
6819 DVIRecoveryRec(DbgVariableRecord *DVR)
6820 : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(
false) {}
6822 DbgVariableRecord *DbgRef;
6824 bool HadLocationArgList;
6830 for (
auto &RE : RecoveryExprs)
6832 RecoveryExprs.clear();
6835 ~DVIRecoveryRec() { clear(); }
6843 auto expr_ops = ToDwarfOpIter(Expr);
6845 for (
auto Op : expr_ops)
6854template <
typename T>
6858 "contain any DW_OP_llvm_arg operands.");
6865template <
typename T>
6870 "Expected expression that references DIArglist locations using "
6871 "DW_OP_llvm_arg operands.");
6873 for (
Value *V : Locations)
6890 if (NumLLVMArgs == 0) {
6897 "Lone LLVM_arg in a DIExpression should refer to location-op 0.");
6927 LLVM_DEBUG(
dbgs() <<
"scev-salvage: restore dbg.value to pre-LSR state\n"
6928 <<
"scev-salvage: post-LSR: " << *DbgVal <<
'\n');
6929 assert(DVIRec.Expr &&
"Expected an expression");
6934 if (!DVIRec.HadLocationArgList) {
6935 assert(DVIRec.LocationOps.size() == 1 &&
6936 "Unexpected number of location ops.");
6940 Value *CachedValue =
6945 for (
WeakVH VH : DVIRec.LocationOps) {
6953 LLVM_DEBUG(
dbgs() <<
"scev-salvage: pre-LSR: " << *DbgVal <<
'\n');
6958 const SCEV *SCEVInductionVar,
6959 SCEVDbgValueBuilder IterCountExpr) {
6973 LocationOpIndexMap.
assign(DVIRec.LocationOps.size(), -1);
6975 NewLocationOps.
push_back(LSRInductionVar);
6977 for (
unsigned i = 0; i < DVIRec.LocationOps.size(); i++) {
6978 WeakVH VH = DVIRec.LocationOps[i];
6984 LocationOpIndexMap[i] = NewLocationOps.
size() - 1;
6986 <<
" now at index " << LocationOpIndexMap[i] <<
"\n");
6994 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV for location at index: " << i
6995 <<
" refers to a location that is now undef or erased. "
6996 "Salvage abandoned.\n");
7000 LLVM_DEBUG(
dbgs() <<
"scev-salvage: salvaging location at index " << i
7001 <<
" with SCEV: " << *DVIRec.SCEVs[i] <<
"\n");
7003 DVIRec.RecoveryExprs[i] = std::make_unique<SCEVDbgValueBuilder>();
7004 SCEVDbgValueBuilder *SalvageExpr = DVIRec.RecoveryExprs[i].get();
7008 if (std::optional<APInt>
Offset =
7010 if (
Offset->getSignificantBits() <= 64)
7011 SalvageExpr->createOffsetExpr(
Offset->getSExtValue(), LSRInductionVar);
7014 }
else if (!SalvageExpr->createIterCountExpr(DVIRec.SCEVs[i], IterCountExpr,
7023 assert(DVIRec.RecoveryExprs.size() == 1 &&
7024 "Expected only a single recovery expression for an empty "
7026 assert(DVIRec.RecoveryExprs[0] &&
7027 "Expected a SCEVDbgSalvageBuilder for location 0");
7028 SCEVDbgValueBuilder *
B = DVIRec.RecoveryExprs[0].get();
7029 B->appendToVectors(
NewExpr, NewLocationOps);
7031 for (
const auto &
Op : DVIRec.Expr->
expr_ops()) {
7039 SCEVDbgValueBuilder *DbgBuilder =
7040 DVIRec.RecoveryExprs[LocationArgIndex].get();
7046 assert(LocationOpIndexMap[
Op.getArg(0)] != -1 &&
7047 "Expected a positive index for the location-op position.");
7048 NewExpr.push_back(LocationOpIndexMap[
Op.getArg(0)]);
7052 DbgBuilder->appendToVectors(
NewExpr, NewLocationOps);
7056 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Updated DVI: " << *DVIRec.DbgRef <<
"\n");
7064 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &DVIToUpdate) {
7065 if (DVIToUpdate.empty())
7069 assert(SCEVInductionVar &&
7070 "Anticipated a SCEV for the post-LSR induction variable");
7074 if (!IVAddRec->isAffine())
7082 SCEVDbgValueBuilder IterCountExpr;
7083 IterCountExpr.pushLocation(LSRInductionVar);
7084 if (!IterCountExpr.SCEVToIterCountExpr(*IVAddRec, SE))
7087 LLVM_DEBUG(
dbgs() <<
"scev-salvage: IV SCEV: " << *SCEVInductionVar
7090 for (
auto &DVIRec : DVIToUpdate) {
7091 SalvageDVI(L, SE, LSRInductionVar, *DVIRec, SCEVInductionVar,
7102 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &SalvageableDVISCEVs) {
7103 for (
const auto &
B : L->getBlocks()) {
7104 for (
auto &
I : *
B) {
7106 if (!DbgVal.isDbgValue() && !DbgVal.isDbgAssign())
7111 if (DbgVal.isKillLocation())
7116 const auto &HasTranslatableLocationOps =
7118 for (
const auto LocOp : DbgValToTranslate.location_ops()) {
7132 if (!HasTranslatableLocationOps(DbgVal))
7135 std::unique_ptr<DVIRecoveryRec> NewRec =
7136 std::make_unique<DVIRecoveryRec>(&DbgVal);
7140 NewRec->RecoveryExprs.resize(DbgVal.getNumVariableLocationOps());
7141 for (
const auto LocOp : DbgVal.location_ops()) {
7142 NewRec->SCEVs.push_back(SE.
getSCEV(LocOp));
7143 NewRec->LocationOps.push_back(LocOp);
7144 NewRec->HadLocationArgList = DbgVal.hasArgList();
7146 SalvageableDVISCEVs.push_back(std::move(NewRec));
7156 const LSRInstance &LSR) {
7158 auto IsSuitableIV = [&](
PHINode *
P) {
7169 for (
const WeakVH &
IV : LSR.getScalarEvolutionIVs()) {
7176 if (IsSuitableIV(
P))
7180 for (
PHINode &
P : L.getHeader()->phis()) {
7181 if (IsSuitableIV(&
P))
7199 std::unique_ptr<MemorySSAUpdater> MSSAU;
7201 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
7204 const LSRInstance &Reducer =
7205 LSRInstance(L, IU, SE, DT, LI,
TTI, AC, TLI, MSSAU.get(), PreserveLCSSA);
7206 Changed |= Reducer.getChanged();
7213#if LLVM_ENABLE_ABI_BREAKING_CHECKS
7216 unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &
TTI);
7230 if (L->isRecursivelyLCSSAForm(DT, LI) && L->getExitBlock()) {
7244 if (SalvageableDVIRecords.
empty())
7250 for (
const auto &L : LI) {
7254 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV salvaging not possible. An IV "
7255 "could not be identified.\n");
7259 for (
auto &Rec : SalvageableDVIRecords)
7261 SalvageableDVIRecords.
clear();
7265bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & ) {
7269 auto &IU = getAnalysis<IVUsersWrapperPass>().getIU();
7270 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
7271 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7272 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
7273 const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
7274 *
L->getHeader()->getParent());
7275 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
7276 *
L->getHeader()->getParent());
7277 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
7278 *
L->getHeader()->getParent());
7279 auto *MSSAAnalysis = getAnalysisIfAvailable<MemorySSAWrapperPass>();
7282 MSSA = &MSSAAnalysis->getMSSA();
7301char LoopStrengthReduce::ID = 0;
7304 "Loop Strength Reduction",
false,
false)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
Function Alias Analysis false
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
early cse Early CSE w MemorySSA
Module.h This file contains the declarations for the Module class.
This defines the Use class.
iv Induction Variable Users
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
This header provides classes for managing per-loop analyses.
static bool SalvageDVI(llvm::Loop *L, ScalarEvolution &SE, llvm::PHINode *LSRInductionVar, DVIRecoveryRec &DVIRec, const SCEV *SCEVInductionVar, SCEVDbgValueBuilder IterCountExpr)
static cl::opt< bool > DropScaledForVScale("lsr-drop-scaled-reg-for-vscale", cl::Hidden, cl::init(true), cl::desc("Avoid using scaled registers with vscale-relative addressing"))
static Value * getWideOperand(Value *Oper)
IVChain logic must consistently peek base TruncInst operands, so wrap it in a convenient helper.
static bool isAddSExtable(const SCEVAddExpr *A, ScalarEvolution &SE)
Return true if the given add can be sign-extended without changing its value.
static bool mayUsePostIncMode(const TargetTransformInfo &TTI, LSRUse &LU, const SCEV *S, const Loop *L, ScalarEvolution &SE)
Return true if the SCEV represents a value that may end up as a post-increment operation.
static void restorePreTransformState(DVIRecoveryRec &DVIRec)
Restore the DVI's pre-LSR arguments. Substitute undef for any erased values.
static bool containsAddRecDependentOnLoop(const SCEV *S, const Loop &L)
static User::op_iterator findIVOperand(User::op_iterator OI, User::op_iterator OE, Loop *L, ScalarEvolution &SE)
Helper for CollectChains that finds an IV operand (computed by an AddRec in this loop) within [OI,...
static cl::opt< TTI::AddressingModeKind > PreferredAddresingMode("lsr-preferred-addressing-mode", cl::Hidden, cl::init(TTI::AMK_None), cl::desc("A flag that overrides the target's preferred addressing mode."), cl::values(clEnumValN(TTI::AMK_None, "none", "Don't prefer any addressing mode"), clEnumValN(TTI::AMK_PreIndexed, "preindexed", "Prefer pre-indexed addressing mode"), clEnumValN(TTI::AMK_PostIndexed, "postindexed", "Prefer post-indexed addressing mode"), clEnumValN(TTI::AMK_All, "all", "Consider all addressing modes")))
static bool isLegalUse(const TargetTransformInfo &TTI, Immediate MinOffset, Immediate MaxOffset, LSRUse::KindType Kind, MemAccessTy AccessTy, GlobalValue *BaseGV, Immediate BaseOffset, bool HasBaseReg, int64_t Scale)
Test whether we know how to expand the current formula.
static void DbgGatherSalvagableDVI(Loop *L, ScalarEvolution &SE, SmallVector< std::unique_ptr< DVIRecoveryRec >, 2 > &SalvageableDVISCEVs)
Identify and cache salvageable DVI locations and expressions along with the corresponding SCEV(s).
static bool isMulSExtable(const SCEVMulExpr *M, ScalarEvolution &SE)
Return true if the given mul can be sign-extended without changing its value.
static const unsigned MaxSCEVSalvageExpressionSize
Limit the size of expression that SCEV-based salvaging will attempt to translate into a DIExpression.
static bool isExistingPhi(const SCEVAddRecExpr *AR, ScalarEvolution &SE)
Return true if this AddRec is already a phi in its loop.
static InstructionCost getScalingFactorCost(const TargetTransformInfo &TTI, const LSRUse &LU, const Formula &F, const Loop &L)
static cl::opt< bool > InsnsCost("lsr-insns-cost", cl::Hidden, cl::init(true), cl::desc("Add instruction count to a LSR cost model"))
static cl::opt< bool > StressIVChain("stress-ivchain", cl::Hidden, cl::init(false), cl::desc("Stress test LSR IV chains"))
static bool isAddressUse(const TargetTransformInfo &TTI, Instruction *Inst, Value *OperandVal)
Returns true if the specified instruction is using the specified value as an address.
static void DoInitialMatch(const SCEV *S, Loop *L, SmallVectorImpl< SCEVUse > &Good, SmallVectorImpl< SCEVUse > &Bad, ScalarEvolution &SE)
Recursion helper for initialMatch.
static void updateDVIWithLocation(T &DbgVal, Value *Location, SmallVectorImpl< uint64_t > &Ops)
Overwrites DVI with the location and Ops as the DIExpression.
static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI, const TargetTransformInfo &TTI, AssumptionCache &AC, TargetLibraryInfo &TLI, MemorySSA *MSSA, bool PreserveLCSSA)
static bool isLegalAddImmediate(const TargetTransformInfo &TTI, Immediate Offset)
static cl::opt< cl::boolOrDefault > AllowDropSolutionIfLessProfitable("lsr-drop-solution", cl::Hidden, cl::desc("Attempt to drop solution if it is less profitable"))
static cl::opt< bool > EnableVScaleImmediates("lsr-enable-vscale-immediates", cl::Hidden, cl::init(true), cl::desc("Enable analysis of vscale-relative immediates in LSR"))
static Instruction * getFixupInsertPos(const TargetTransformInfo &TTI, const LSRFixup &Fixup, const LSRUse &LU, Instruction *IVIncInsertPos, DominatorTree &DT)
static const SCEV * getExprBase(const SCEV *S)
Return an approximation of this SCEV expression's "base", or NULL for any constant.
static bool isAlwaysFoldable(const TargetTransformInfo &TTI, LSRUse::KindType Kind, MemAccessTy AccessTy, GlobalValue *BaseGV, Immediate BaseOffset, bool HasBaseReg)
static llvm::PHINode * GetInductionVariable(const Loop &L, ScalarEvolution &SE, const LSRInstance &LSR)
Ideally pick the PHI IV inserted by ScalarEvolutionExpander.
static bool IsSimplerBaseSCEVForTarget(const TargetTransformInfo &TTI, ScalarEvolution &SE, const SCEV *Best, const SCEV *Reg, MemAccessTy AccessType)
static const unsigned MaxIVUsers
MaxIVUsers is an arbitrary threshold that provides an early opportunity for bail out.
static bool isHighCostExpansion(const SCEV *S, SmallPtrSetImpl< const SCEV * > &Processed, ScalarEvolution &SE)
Check if expanding this expression is likely to incur significant cost.
static Value * getValueOrPoison(WeakVH &VH, LLVMContext &C)
Cached location ops may be erased during LSR, in which case a poison is required when restoring from ...
static MemAccessTy getAccessType(const TargetTransformInfo &TTI, Instruction *Inst, Value *OperandVal)
Return the type of the memory being accessed.
static unsigned numLLVMArgOps(SmallVectorImpl< uint64_t > &Expr)
Returns the total number of DW_OP_llvm_arg operands in the expression.
static Immediate ExtractImmediate(SCEVUse &S, ScalarEvolution &SE, bool PreferScalable=false)
If S involves the addition of a constant integer value, return that integer value,...
static void DbgRewriteSalvageableDVIs(llvm::Loop *L, ScalarEvolution &SE, llvm::PHINode *LSRInductionVar, SmallVector< std::unique_ptr< DVIRecoveryRec >, 2 > &DVIToUpdate)
Obtain an expression for the iteration count, then attempt to salvage the dbg.value intrinsics.
static cl::opt< bool > EnablePhiElim("enable-lsr-phielim", cl::Hidden, cl::init(true), cl::desc("Enable LSR phi elimination"))
static void UpdateDbgValue(DVIRecoveryRec &DVIRec, SmallVectorImpl< Value * > &NewLocationOps, SmallVectorImpl< uint64_t > &NewExpr)
Write the new expression and new location ops for the dbg.value.
static bool isAddRecSExtable(const SCEVAddRecExpr *AR, ScalarEvolution &SE)
Return true if the given addrec can be sign-extended without changing its value.
static Immediate ExtractImmediateOperand(MutableArrayRef< SCEVUse > Ops, ScalarEvolution &SE, bool PreferScalable)
Extracts an immediate operand from Ops and replaces the operand with zero.
static bool isAMCompletelyFolded(const TargetTransformInfo &TTI, const LSRUse &LU, const Formula &F)
Check if the addressing mode defined by F is completely folded in LU at isel time.
static cl::opt< bool > LSRExpNarrow("lsr-exp-narrow", cl::Hidden, cl::init(false), cl::desc("Narrow LSR complex solution using" " expectation of registers number"))
static cl::opt< bool > FilterSameScaledReg("lsr-filter-same-scaled-reg", cl::Hidden, cl::init(true), cl::desc("Narrow LSR search space by filtering non-optimal formulae" " with the same ScaledReg and Scale"))
static void updateDVIWithLocations(T &DbgVal, SmallVectorImpl< Value * > &Locations, SmallVectorImpl< uint64_t > &Ops)
Overwrite DVI with locations placed into a DIArglist.
static cl::opt< unsigned > ComplexityLimit("lsr-complexity-limit", cl::Hidden, cl::init(std::numeric_limits< uint16_t >::max()), cl::desc("LSR search space complexity limit"))
static GlobalValue * ExtractSymbol(SCEVUse &S, ScalarEvolution &SE)
If S involves the addition of a GlobalValue address, return that symbol, and mutate S to point to a n...
static bool isProfitableChain(IVChain &Chain, SmallPtrSetImpl< Instruction * > &Users, ScalarEvolution &SE, const TargetTransformInfo &TTI)
Return true if the number of registers needed for the chain is estimated to be less than the number r...
static const SCEV * CollectSubexprs(const SCEV *S, const SCEVConstant *C, SmallVectorImpl< const SCEV * > &Ops, const Loop *L, ScalarEvolution &SE, unsigned Depth=0)
Split S into subexpressions which can be pulled out into separate registers.
static const SCEV * getExactSDiv(const SCEV *LHS, const SCEV *RHS, ScalarEvolution &SE, bool IgnoreSignificantBits=false)
Return an expression for LHS /s RHS, if it can be determined and if the remainder is known to be zero...
static bool canFoldIVIncExpr(const SCEV *IncExpr, Instruction *UserInst, Value *Operand, const TargetTransformInfo &TTI)
Return true if the IVInc can be folded into an addressing mode.
static const SCEV * getAnyExtendConsideringPostIncUses(ArrayRef< PostIncLoopSet > Loops, const SCEV *Expr, Type *ToTy, ScalarEvolution &SE)
Extend/Truncate Expr to ToTy considering post-inc uses in Loops.
static unsigned getSetupCost(const SCEV *Reg, unsigned Depth, const TargetTransformInfo &TTI)
static cl::opt< unsigned > SetupCostDepthLimit("lsr-setupcost-depth-limit", cl::Hidden, cl::init(7), cl::desc("The limit on recursion depth for LSRs setup cost"))
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
uint64_t IntrinsicInst * II
PowerPC TLS Dynamic Call Fixup
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the PointerIntPair class.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
SI optimize exec mask operations pre RA
This file implements a set that has insertion order iteration characteristics.
This file implements the SmallBitVector class.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static const unsigned UnknownAddressSpace
static SymbolRef::Type getType(const Symbol *Sym)
Virtual Register Rewriter
static const uint32_t IV[8]
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
LLVM_ABI APInt srem(const APInt &RHS) const
Function for signed remainder operation.
int64_t getSExtValue() const
Get sign extended value.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
LLVM_ABI AnalysisUsage & addRequiredID(const void *ID)
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
InstListType::iterator iterator
Instruction iterators...
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...
LLVM_ABI bool isLandingPad() const
Return true if this basic block is a landing pad.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static LLVM_ABI Instruction::CastOps getCastOpcode(const Value *Val, bool SrcIsSigned, Type *Ty, bool DstIsSigned)
Returns the opcode necessary to cast Val into Ty using usual casting rules.
static LLVM_ABI CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Value * getCondition() const
static LLVM_ABI bool isValueValidForType(Type *Ty, uint64_t V)
This static method returns true if the type Ty is big enough to represent the value V.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
iterator_range< expr_op_iterator > expr_ops() const
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
LLVM_ABI bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
LLVM_ABI LLVMContext & getContext()
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI bool isKillLocation() const
void setRawLocation(Metadata *NewLocation)
Use of this should generally be avoided; instead, replaceVariableLocationOp and addVariableLocationOp...
void setExpression(DIExpression *NewExpr)
DIExpression * getExpression() const
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
PointerType * getType() const
Global values are always pointers.
IVStrideUse - Keep track of one use of a strided induction variable.
void transformToPostInc(const Loop *L)
transformToPostInc - Transform the expression to post-inc form for the given loop.
Value * getOperandValToReplace() const
getOperandValToReplace - Return the Value of the operand in the user instruction that this IVStrideUs...
void setUser(Instruction *NewUser)
setUser - Assign a new user instruction for this use.
Analysis pass that exposes the IVUsers for a loop.
ilist< IVStrideUse >::const_iterator const_iterator
LLVM_ABI void print(raw_ostream &OS) const
CostType getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI Type * getAccessType() const LLVM_READONLY
Return the type this instruction accesses in memory, if any.
const char * getOpcodeName() const
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
BlockT * getHeader() const
unsigned getLoopDepth() const
Return the nesting level of this loop.
The legacy pass manager's analysis pass to compute loop information.
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
An analysis that produces MemorySSA for a function.
Encapsulates MemorySSA, including all data associated with memory accesses.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
iterator_range< const_block_iterator > blocks() const
op_range incoming_values()
void setIncomingValue(unsigned i, Value *V)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
static unsigned getIncomingValueNumForOperand(unsigned i)
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This node represents an addition of some number of SCEVs.
This node represents a polynomial recurrence on the trip count of the specified loop.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class represents a constant integer value.
ConstantInt * getValue() const
const APInt & getAPInt() const
This class uses information about analyze scalars to rewrite expressions in canonical form.
This node represents multiplication of some number of SCEVs.
bool hasNoUnsignedWrap() const
ArrayRef< SCEVUse > operands() const
bool hasNoSignedWrap() const
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
This class represents an analyzed expression in the program.
unsigned short getExpressionSize() const
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
static constexpr auto FlagAnyWrap
LLVM_ABI ArrayRef< SCEVUse > operands() const
Return operands of this SCEV expression.
SCEVTypes getSCEVType() const
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
LLVM_ABI const SCEV * getNoopOrSignExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI Type * getEffectiveSCEVType(Type *Ty) const
Return a type with the same bitwidth as the given type and which represents how SCEV will treat the g...
LLVM_ABI const SCEV * getAnyExtendExpr(const SCEV *Op, Type *Ty)
getAnyExtendExpr - Return a SCEV for the given operand extended with unspecified bits out to the give...
LLVM_ABI bool containsUndefs(const SCEV *S) const
Return true if the SCEV expression contains an undef value.
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getVScale(Type *Ty)
LLVM_ABI bool hasComputableLoopEvolution(const SCEV *S, const Loop *L)
Return true if the given SCEV changes value in a known way in the specified loop.
LLVM_ABI const SCEV * getPointerBase(const SCEV *V)
Transitively follow the chain of pointer-type operands until reaching a SCEV that does not have a sin...
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getUnknown(Value *V)
LLVM_ABI std::optional< APInt > computeConstantDifference(const SCEV *LHS, const SCEV *RHS)
Compute LHS - RHS and returns the result as an APInt if it is a constant, and std::nullopt if it isn'...
LLVM_ABI bool properlyDominates(const SCEV *S, const BasicBlock *BB)
Return true if elements that makes up the given SCEV properly dominate the specified basic block.
LLVM_ABI bool containsErasedValue(const SCEV *S) const
Return true if the SCEV expression contains a Value that has been optimised out and is now a nullptr.
LLVMContext & getContext() const
size_type size() const
Determine the number of elements in the SetVector.
iterator end()
Get an iterator to the end of the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
iterator_range< const_set_bits_iterator > set_bits() const
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
size_type size() const
Returns the number of bits in this bitvector.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
size_type count() const
Returns the number of bits which are set.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
typename SuperClass::const_iterator const_iterator
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static StackOffset get(int64_t Fixed, int64_t Scalable)
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
bool isVoidTy() const
Return true if this is 'void'.
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
iterator_range< use_iterator > uses()
A nullable Value handle that is nullable.
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
bind_cst_ty m_scev_APInt(const APInt *&C)
Match an SCEV constant and bind it to an APInt.
match_bind< const SCEVMulExpr > m_scev_Mul(const SCEVMulExpr *&V)
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
cst_pred_ty< is_specific_cst > m_scev_SpecificInt(uint64_t V)
Match an SCEV constant with a plain unsigned integer.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI iterator begin() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned KindType
For isa, dyn_cast, etc operations on TelemetryInfo.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
bool operator!=(uint64_t V1, const APInt &V2)
LLVM_ABI bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, SmallPtrSetImpl< PHINode * > *KnownNonDeadPHIs=nullptr)
Examine each PHI in the given block and delete it if it is dead.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
LLVM_ABI char & LoopSimplifyID
bool isa_and_nonnull(const Y &Val)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
DomTreeNodeBase< BasicBlock > DomTreeNode
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI void initializeLoopStrengthReducePass(PassRegistry &)
auto reverse(ContainerTy &&C)
LLVM_ABI const SCEV * denormalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops, ScalarEvolution &SE)
Denormalize S to be post-increment for all loops present in Loops.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef< BasicBlock * > Preds, const char *Suffix, const char *Suffix2, SmallVectorImpl< BasicBlock * > &NewBBs, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method transforms the landing pad, OrigBB, by introducing two new basic blocks into the function...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI const SCEV * normalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops, ScalarEvolution &SE, bool CheckInvertible=true)
Normalize S to be post-increment for all loops present in Loops.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
LLVM_ABI Pass * createLoopStrengthReducePass()
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
constexpr unsigned BitWidth
LLVM_ABI bool formLCSSAForInstructions(SmallVectorImpl< Instruction * > &Worklist, const DominatorTree &DT, const LoopInfo &LI, ScalarEvolution *SE, SmallVectorImpl< PHINode * > *PHIsToRemove=nullptr, SmallVectorImpl< PHINode * > *InsertedPHIs=nullptr)
Ensures LCSSA form for every instruction from the Worklist in the scope of innermost containing loop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
SmallPtrSet< const Loop *, 2 > PostIncLoopSet
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI int rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI, ScalarEvolution *SE, const TargetTransformInfo *TTI, SCEVExpander &Rewriter, DominatorTree *DT, ReplaceExitVal ReplaceExitValue, SmallVector< WeakTrackingVH, 16 > &DeadInsts)
If the final value of any expressions that are recurrent in the loop can be computed,...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
SCEVUseT< const SCEV * > SCEVUse
bool SCEVExprContains(const SCEV *Root, PredTy Pred)
Return true if any node in Root satisfies the predicate Pred.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Attributes of a target dependent hardware loop.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI
Information about a load/store intrinsic defined by the target.
Value * PtrVal
This is the pointer that the intrinsic is loading from or storing to.