133#define DEBUG_TYPE "loop-reduce"
151 cl::desc(
"Stress test LSR IV chains"));
161 std::numeric_limits<unsigned>::max();
163 Type *MemTy =
nullptr;
166 MemAccessTy() =
default;
167 MemAccessTy(
Type *Ty,
unsigned AS) : MemTy(Ty), AddrSpace(AS) {}
170 return MemTy ==
Other.MemTy && AddrSpace ==
Other.AddrSpace;
175 static MemAccessTy getUnknown(LLVMContext &Ctx,
176 unsigned AS = UnknownAddressSpace) {
177 return MemAccessTy(Type::getVoidTy(Ctx), AS);
188 SmallBitVector UsedByIndices;
190 void print(raw_ostream &OS)
const;
197 constexpr Immediate(ScalarTy MinVal,
bool Scalable)
198 : FixedOrScalableQuantity(MinVal, Scalable) {}
200 constexpr Immediate(
const FixedOrScalableQuantity<Immediate, int64_t> &V)
201 : FixedOrScalableQuantity(
V) {}
204 constexpr Immediate() =
delete;
206 static constexpr Immediate getFixed(ScalarTy MinVal) {
207 return {MinVal,
false};
209 static constexpr Immediate getScalable(ScalarTy MinVal) {
210 return {MinVal,
true};
212 static constexpr Immediate
get(ScalarTy MinVal,
bool Scalable) {
213 return {MinVal, Scalable};
215 static constexpr Immediate getZero() {
return {0,
false}; }
216 static constexpr Immediate getFixedMin() {
217 return {std::numeric_limits<int64_t>::min(),
false};
219 static constexpr Immediate getFixedMax() {
220 return {std::numeric_limits<int64_t>::max(),
false};
222 static constexpr Immediate getScalableMin() {
223 return {std::numeric_limits<int64_t>::min(),
true};
225 static constexpr Immediate getScalableMax() {
226 return {std::numeric_limits<int64_t>::max(),
true};
229 constexpr bool isLessThanZero()
const {
return Quantity < 0; }
231 constexpr bool isGreaterThanZero()
const {
return Quantity > 0; }
233 constexpr bool isCompatibleImmediate(
const Immediate &
Imm)
const {
234 return isZero() ||
Imm.isZero() ||
Imm.Scalable == Scalable;
237 constexpr bool isMin()
const {
238 return Quantity == std::numeric_limits<ScalarTy>::min();
241 constexpr bool isMax()
const {
242 return Quantity == std::numeric_limits<ScalarTy>::max();
246 constexpr Immediate addUnsigned(
const Immediate &
RHS)
const {
247 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
249 return {
Value, Scalable ||
RHS.isScalable()};
252 constexpr Immediate subUnsigned(
const Immediate &
RHS)
const {
253 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
255 return {
Value, Scalable ||
RHS.isScalable()};
259 constexpr Immediate mulUnsigned(
const ScalarTy
RHS)
const {
261 return {
Value, Scalable};
265 const SCEV *getSCEV(ScalarEvolution &SE,
Type *Ty)
const {
272 const SCEV *getNegativeSCEV(ScalarEvolution &SE,
Type *Ty)
const {
279 const SCEV *getUnknownSCEV(ScalarEvolution &SE,
Type *Ty)
const {
294struct KeyOrderTargetImmediate {
295 bool operator()(
const Immediate &
LHS,
const Immediate &
RHS)
const {
296 if (
LHS.isScalable() && !
RHS.isScalable())
298 if (!
LHS.isScalable() &&
RHS.isScalable())
300 return LHS.getKnownMinValue() <
RHS.getKnownMinValue();
307struct KeyOrderSizeTAndImmediate {
308 bool operator()(
const std::pair<size_t, Immediate> &
LHS,
309 const std::pair<size_t, Immediate> &
RHS)
const {
310 size_t LSize =
LHS.first;
311 size_t RSize =
RHS.first;
313 return LSize < RSize;
314 return KeyOrderTargetImmediate()(
LHS.second,
RHS.second);
319#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
321 OS <<
"[NumUses=" << UsedByIndices.
count() <<
']';
333 using RegUsesTy = DenseMap<const SCEV *, RegSortData>;
335 RegUsesTy RegUsesMap;
339 void countRegister(
const SCEV *
Reg,
size_t LUIdx);
340 void dropRegister(
const SCEV *
Reg,
size_t LUIdx);
341 void swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx);
343 bool isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const;
345 const SmallBitVector &getUsedByIndices(
const SCEV *
Reg)
const;
361RegUseTracker::countRegister(
const SCEV *
Reg,
size_t LUIdx) {
362 std::pair<RegUsesTy::iterator, bool> Pair = RegUsesMap.try_emplace(
Reg);
363 RegSortData &RSD = Pair.first->second;
366 RSD.UsedByIndices.
resize(std::max(RSD.UsedByIndices.
size(), LUIdx + 1));
367 RSD.UsedByIndices.
set(LUIdx);
371RegUseTracker::dropRegister(
const SCEV *
Reg,
size_t LUIdx) {
372 RegUsesTy::iterator It = RegUsesMap.find(
Reg);
373 assert(It != RegUsesMap.end());
374 RegSortData &RSD = It->second;
376 RSD.UsedByIndices.
reset(LUIdx);
380RegUseTracker::swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx) {
381 assert(LUIdx <= LastLUIdx);
385 for (
auto &Pair : RegUsesMap) {
386 SmallBitVector &UsedByIndices = Pair.second.UsedByIndices;
387 if (LUIdx < UsedByIndices.
size())
388 UsedByIndices[LUIdx] =
389 LastLUIdx < UsedByIndices.
size() ? UsedByIndices[LastLUIdx] :
false;
390 UsedByIndices.
resize(std::min(UsedByIndices.
size(), LastLUIdx));
395RegUseTracker::isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const {
396 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
397 if (
I == RegUsesMap.end())
399 const SmallBitVector &UsedByIndices =
I->second.UsedByIndices;
401 if (i == -1)
return false;
402 if ((
size_t)i != LUIdx)
return true;
406const SmallBitVector &RegUseTracker::getUsedByIndices(
const SCEV *
Reg)
const {
407 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
408 assert(
I != RegUsesMap.end() &&
"Unknown register!");
409 return I->second.UsedByIndices;
412void RegUseTracker::clear() {
423 GlobalValue *BaseGV =
nullptr;
426 Immediate BaseOffset = Immediate::getZero();
429 bool HasBaseReg =
false;
452 const SCEV *ScaledReg =
nullptr;
457 Immediate UnfoldedOffset = Immediate::getZero();
461 void initialMatch(
const SCEV *S,
Loop *L, ScalarEvolution &SE);
465 void canonicalize(
const Loop &L);
469 bool hasZeroEnd()
const;
471 bool countsDownToZero()
const;
473 size_t getNumRegs()
const;
476 void deleteBaseReg(
const SCEV *&S);
478 bool referencesReg(
const SCEV *S)
const;
479 bool hasRegsUsedByUsesOtherThan(
size_t LUIdx,
480 const RegUseTracker &RegUses)
const;
482 void print(raw_ostream &OS)
const;
500 for (
const SCEV *S :
Add->operands())
506 const SCEV *Start, *Step;
521 if (
Mul->getOperand(0)->isAllOnesValue()) {
530 for (
const SCEV *S : MyGood)
532 for (
const SCEV *S : MyBad)
544void Formula::initialMatch(
const SCEV *S,
Loop *L, ScalarEvolution &SE) {
551 BaseRegs.push_back(Sum);
557 BaseRegs.push_back(Sum);
572bool Formula::isCanonical(
const Loop &L)
const {
573 assert((Scale == 0 || ScaledReg) &&
574 "ScaledReg must be non-null if Scale is non-zero");
577 return BaseRegs.size() <= 1;
582 if (Scale == 1 && BaseRegs.empty())
591 return none_of(BaseRegs, [&L](
const SCEV *S) {
602void Formula::canonicalize(
const Loop &L) {
606 if (BaseRegs.empty()) {
608 assert(ScaledReg &&
"Expected 1*reg => reg");
609 assert(Scale == 1 &&
"Expected 1*reg => reg");
610 BaseRegs.push_back(ScaledReg);
618 ScaledReg = BaseRegs.pop_back_val();
626 auto I =
find_if(BaseRegs, [&L](
const SCEV *S) {
629 if (
I != BaseRegs.end())
639bool Formula::unscale() {
643 BaseRegs.push_back(ScaledReg);
648bool Formula::hasZeroEnd()
const {
649 if (UnfoldedOffset || BaseOffset)
651 if (BaseRegs.size() != 1 || ScaledReg)
656bool Formula::countsDownToZero()
const {
659 assert(BaseRegs.size() == 1 &&
"hasZeroEnd should mean one BaseReg");
660 const APInt *StepInt;
668size_t Formula::getNumRegs()
const {
669 return !!ScaledReg + BaseRegs.size();
674Type *Formula::getType()
const {
675 return !BaseRegs.empty() ? BaseRegs.front()->getType() :
676 ScaledReg ? ScaledReg->
getType() :
682void Formula::deleteBaseReg(
const SCEV *&S) {
683 if (&S != &BaseRegs.back())
689bool Formula::referencesReg(
const SCEV *S)
const {
695bool Formula::hasRegsUsedByUsesOtherThan(
size_t LUIdx,
696 const RegUseTracker &RegUses)
const {
698 if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
700 for (
const SCEV *BaseReg : BaseRegs)
701 if (RegUses.isRegUsedByUsesOtherThan(BaseReg, LUIdx))
706#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
707void Formula::print(raw_ostream &OS)
const {
708 ListSeparator
Plus(
" + ");
713 if (BaseOffset.isNonZero())
714 OS <<
Plus << BaseOffset;
716 for (
const SCEV *BaseReg : BaseRegs)
719 if (HasBaseReg && BaseRegs.empty())
720 OS <<
Plus <<
"**error: HasBaseReg**";
721 else if (!HasBaseReg && !BaseRegs.empty())
722 OS <<
Plus <<
"**error: !HasBaseReg**";
725 OS <<
Plus << Scale <<
"*reg(";
732 if (UnfoldedOffset.isNonZero())
733 OS <<
Plus <<
"imm(" << UnfoldedOffset <<
')';
773 bool IgnoreSignificantBits =
false) {
784 if (
RA.isAllOnes()) {
785 if (
LHS->getType()->isPointerTy())
798 const APInt &LA =
C->getAPInt();
807 if ((IgnoreSignificantBits ||
isAddRecSExtable(AR, SE)) && AR->isAffine()) {
809 IgnoreSignificantBits);
810 if (!Step)
return nullptr;
812 IgnoreSignificantBits);
813 if (!Start)
return nullptr;
826 for (
const SCEV *S :
Add->operands()) {
828 if (!
Op)
return nullptr;
856 for (
const SCEV *S :
Mul->operands()) {
859 IgnoreSignificantBits)) {
880 bool PreferScalable) {
883 Immediate Result = Immediate::getZero();
892 C->getSignificantBits() <= 64) {
894 Result = Immediate::getFixed(
C->getSExtValue());
899 if (Opts.lsr_enable_vscale_immediates &&
900 (Result.isZero() || PreferScalable)) {
907 Result = Immediate::getScalable(
C->getSExtValue());
913 if (Result.isNonZero()) {
925 bool PreferScalable =
false) {
932 if (Result.isNonZero())
939 if (Result.isNonZero())
980 if (
SI->getPointerOperand() == OperandVal)
985 switch (
II->getIntrinsicID()) {
986 case Intrinsic::memset:
987 case Intrinsic::prefetch:
988 case Intrinsic::masked_load:
989 if (
II->getArgOperand(0) == OperandVal)
992 case Intrinsic::masked_store:
993 if (
II->getArgOperand(1) == OperandVal)
996 case Intrinsic::memmove:
997 case Intrinsic::memcpy:
998 if (
II->getArgOperand(0) == OperandVal ||
999 II->getArgOperand(1) == OperandVal)
1004 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo)) {
1005 if (IntrInfo.
PtrVal == OperandVal)
1011 if (RMW->getPointerOperand() == OperandVal)
1014 if (CmpX->getPointerOperand() == OperandVal)
1023 MemAccessTy AccessTy = MemAccessTy::getUnknown(Inst->
getContext());
1027 AccessTy.MemTy = Ty;
1031 AccessTy.AddrSpace =
SI->getPointerAddressSpace();
1033 AccessTy.AddrSpace = LI->getPointerAddressSpace();
1035 AccessTy.AddrSpace = RMW->getPointerAddressSpace();
1037 AccessTy.AddrSpace = CmpX->getPointerAddressSpace();
1039 switch (
II->getIntrinsicID()) {
1040 case Intrinsic::prefetch:
1041 case Intrinsic::memset:
1042 AccessTy.AddrSpace =
II->getArgOperand(0)->getType()->getPointerAddressSpace();
1043 AccessTy.MemTy = OperandVal->
getType();
1045 case Intrinsic::memmove:
1046 case Intrinsic::memcpy:
1048 AccessTy.MemTy = OperandVal->
getType();
1050 case Intrinsic::masked_load:
1051 AccessTy.AddrSpace =
1052 II->getArgOperand(0)->getType()->getPointerAddressSpace();
1054 case Intrinsic::masked_store:
1055 AccessTy.AddrSpace =
1056 II->getArgOperand(1)->getType()->getPointerAddressSpace();
1060 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo) && IntrInfo.
PtrVal) {
1116 if (!Processed.
insert(S).second)
1120 for (
const SCEV *S :
Add->operands()) {
1127 const SCEV *Op0, *Op1;
1136 Value *UVal = U->getValue();
1140 if (UI && UI->
getOpcode() == Instruction::Mul &&
1173 const LSRUse &LU,
const Formula &
F);
1177 const LSRUse &LU,
const Formula &
F,
1184 const ScalarOptions *Opts =
nullptr;
1185 const Loop *
L =
nullptr;
1186 ScalarEvolution *SE =
nullptr;
1187 const TargetTransformInfo *
TTI =
nullptr;
1188 TargetTransformInfo::LSRCost
C;
1193 Cost(
const ScalarOptions &Opts,
const Loop *L, ScalarEvolution &SE,
1195 : Opts(&Opts),
L(
L), SE(&SE),
TTI(&
TTI), AMK(AMK) {
1213 return ((
C.Insns |
C.NumRegs |
C.AddRecCost |
C.NumIVMuls |
C.NumBaseAdds
1214 |
C.ImmCost |
C.SetupCost |
C.ScaleCost) != ~0u)
1215 || ((
C.Insns &
C.NumRegs &
C.AddRecCost &
C.NumIVMuls &
C.NumBaseAdds
1216 &
C.ImmCost &
C.SetupCost &
C.ScaleCost) == ~0
u);
1222 return C.NumRegs == ~0
u;
1225 void RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1226 const DenseSet<const SCEV *> &VisitedRegs,
const LSRUse &LU,
1227 bool HardwareLoopProfitable,
1228 SmallPtrSetImpl<const SCEV *> *LoserRegs =
nullptr);
1230 void print(raw_ostream &OS)
const;
1234 void RateRegister(
const Formula &
F,
const SCEV *
Reg,
1235 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1236 bool HardwareLoopProfitable);
1237 void RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1238 SmallPtrSetImpl<const SCEV *> &Regs,
1239 const LSRUse &LU,
bool HardwareLoopProfitable,
1240 SmallPtrSetImpl<const SCEV *> *LoserRegs);
1251 Value *OperandValToReplace =
nullptr;
1261 Immediate
Offset = Immediate::getZero();
1263 LSRFixup() =
default;
1265 bool isUseFullyOutsideLoop(
const Loop *L)
const;
1267 void print(raw_ostream &OS)
const;
1277 DenseSet<SmallVector<const SCEV *, 4>> Uniquifier;
1290 using SCEVUseKindPair = PointerIntPair<const SCEV *, 2, KindType>;
1293 MemAccessTy AccessTy;
1299 Immediate MinOffset = Immediate::getFixedMax();
1300 Immediate MaxOffset = Immediate::getFixedMin();
1304 bool AllFixupsOutsideLoop =
true;
1309 bool AllFixupsUnconditional =
true;
1316 bool RigidFormula =
false;
1324 SmallPtrSet<const SCEV *, 4> Regs;
1326 LSRUse(KindType K, MemAccessTy AT) :
Kind(
K), AccessTy(AT) {}
1328 LSRFixup &getNewFixup() {
1329 Fixups.push_back(LSRFixup());
1333 void pushFixup(LSRFixup &f) {
1335 if (Immediate::isKnownGT(
f.Offset, MaxOffset))
1336 MaxOffset =
f.Offset;
1337 if (Immediate::isKnownLT(
f.Offset, MinOffset))
1338 MinOffset =
f.Offset;
1341 bool HasFormulaWithSameRegs(
const Formula &
F)
const;
1342 float getNotSelectedProbability(
const SCEV *
Reg)
const;
1343 bool InsertFormula(
const Formula &
F,
const Loop &L);
1344 void DeleteFormula(Formula &
F);
1345 void RecomputeRegs(
size_t LUIdx, RegUseTracker &Reguses);
1347 void print(raw_ostream &OS)
const;
1354 LSRUse::KindType Kind, MemAccessTy AccessTy,
1355 GlobalValue *BaseGV, Immediate BaseOffset,
1356 bool HasBaseReg, int64_t Scale,
1357 Instruction *
Fixup =
nullptr);
1364 if (
TTI.getIntImmCost(
C->getAPInt(),
C->getType(),
1378 [&](
unsigned i,
const SCEV *
Reg) {
1379 return i + getSetupCost(Reg, Depth - 1, TTI);
1388void Cost::RateRegister(
const Formula &
F,
const SCEV *
Reg,
1389 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1390 bool HardwareLoopProfitable) {
1395 if (AR->getLoop() != L) {
1402 if (!AR->getLoop()->contains(L)) {
1412 unsigned LoopCost = 1;
1421 F.BaseOffset.isFixed() &&
1422 *Step ==
F.BaseOffset.getFixedValue();
1427 if ((CanPreIndex || CanPostIndex) && LU.AllFixupsUnconditional)
1434 if (LU.Kind == LSRUse::ICmpZero &&
F.countsDownToZero() &&
1435 HardwareLoopProfitable)
1437 C.AddRecCost += LoopCost;
1441 const SCEV *StepReg = AR->getOperand(1);
1446 auto IsVScaleStep = [](
const SCEV *
Reg,
const TargetTransformInfo *
TTI) {
1452 if (!Regs.
count(StepReg) && !IsVScaleStep(StepReg,
TTI)) {
1453 RateRegister(
F, StepReg, Regs, LU, HardwareLoopProfitable);
1465 C.SetupCost = std::min<unsigned>(
C.SetupCost, 1 << 16);
1474void Cost::RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1475 SmallPtrSetImpl<const SCEV *> &Regs,
1476 const LSRUse &LU,
bool HardwareLoopProfitable,
1477 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1478 if (LoserRegs && LoserRegs->
count(
Reg)) {
1483 RateRegister(
F,
Reg, Regs, LU, HardwareLoopProfitable);
1484 if (LoserRegs && isLoser())
1489void Cost::RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1490 const DenseSet<const SCEV *> &VisitedRegs,
1491 const LSRUse &LU,
bool HardwareLoopProfitable,
1492 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1495 assert(
F.isCanonical(*L) &&
"Cost is accurate only for canonical formula");
1497 unsigned PrevAddRecCost =
C.AddRecCost;
1498 unsigned PrevNumRegs =
C.NumRegs;
1499 unsigned PrevNumBaseAdds =
C.NumBaseAdds;
1500 if (
const SCEV *ScaledReg =
F.ScaledReg) {
1501 if (VisitedRegs.
count(ScaledReg)) {
1505 RatePrimaryRegister(
F, ScaledReg, Regs, LU, HardwareLoopProfitable,
1510 for (
const SCEV *BaseReg :
F.BaseRegs) {
1511 if (VisitedRegs.
count(BaseReg)) {
1515 RatePrimaryRegister(
F, BaseReg, Regs, LU, HardwareLoopProfitable,
1522 size_t NumBaseParts =
F.getNumRegs();
1523 if (NumBaseParts > 1)
1528 C.NumBaseAdds += (
F.UnfoldedOffset.isNonZero());
1534 for (
const LSRFixup &
Fixup : LU.Fixups) {
1535 if (
Fixup.Offset.isCompatibleImmediate(
F.BaseOffset)) {
1536 Immediate
Offset =
Fixup.Offset.addUnsigned(
F.BaseOffset);
1540 else if (
Offset.isNonZero())
1542 APInt(64,
Offset.getKnownMinValue(),
true).getSignificantBits();
1546 if (LU.Kind == LSRUse::Address &&
Offset.isNonZero() &&
1557 if (!
valueOr(Opts->lsr_insns_cost,
true)) {
1567 if (
C.NumRegs > TTIRegNum) {
1570 if (PrevNumRegs > TTIRegNum)
1571 C.Insns += (
C.NumRegs - PrevNumRegs);
1573 C.Insns += (
C.NumRegs - TTIRegNum);
1586 if (LU.Kind == LSRUse::ICmpZero && !
F.hasZeroEnd() &&
1590 C.Insns += (
C.AddRecCost - PrevAddRecCost);
1593 if (LU.Kind != LSRUse::ICmpZero)
1594 C.Insns +=
C.NumBaseAdds - PrevNumBaseAdds;
1600 C.Insns = std::numeric_limits<unsigned>::max();
1601 C.NumRegs = std::numeric_limits<unsigned>::max();
1602 C.AddRecCost = std::numeric_limits<unsigned>::max();
1603 C.NumIVMuls = std::numeric_limits<unsigned>::max();
1604 C.NumBaseAdds = std::numeric_limits<unsigned>::max();
1605 C.ImmCost = std::numeric_limits<unsigned>::max();
1606 C.SetupCost = std::numeric_limits<unsigned>::max();
1607 C.ScaleCost = std::numeric_limits<unsigned>::max();
1611bool Cost::isLess(
const Cost &
Other)
const {
1612 if (Opts->lsr_insns_cost == BoolOrDefault::True &&
C.Insns !=
Other.C.Insns)
1613 return C.Insns <
Other.C.Insns;
1617#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1619 if (
valueOr(Opts->lsr_insns_cost,
true))
1620 OS <<
C.Insns <<
" instruction" << (
C.Insns == 1 ?
" " :
"s ");
1621 OS <<
C.NumRegs <<
" reg" << (
C.NumRegs == 1 ?
"" :
"s");
1622 if (
C.AddRecCost != 0)
1623 OS <<
", with addrec cost " <<
C.AddRecCost;
1624 if (
C.NumIVMuls != 0)
1625 OS <<
", plus " <<
C.NumIVMuls <<
" IV mul"
1626 << (
C.NumIVMuls == 1 ?
"" :
"s");
1627 if (
C.NumBaseAdds != 0)
1628 OS <<
", plus " <<
C.NumBaseAdds <<
" base add"
1629 << (
C.NumBaseAdds == 1 ?
"" :
"s");
1630 if (
C.ScaleCost != 0)
1631 OS <<
", plus " <<
C.ScaleCost <<
" scale cost";
1633 OS <<
", plus " <<
C.ImmCost <<
" imm cost";
1634 if (
C.SetupCost != 0)
1635 OS <<
", plus " <<
C.SetupCost <<
" setup cost";
1644bool LSRFixup::isUseFullyOutsideLoop(
const Loop *L)
const {
1647 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1648 if (PN->getIncomingValue(i) == OperandValToReplace &&
1649 L->contains(PN->getIncomingBlock(i)))
1654 return !
L->contains(UserInst);
1657#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1658void LSRFixup::print(raw_ostream &OS)
const {
1663 Store->getOperand(0)->printAsOperand(OS,
false);
1669 OS <<
", OperandValToReplace=";
1672 for (
const Loop *PIL : PostIncLoops) {
1673 OS <<
", PostIncLoop=";
1674 PIL->getHeader()->printAsOperand(OS,
false);
1678 OS <<
", Offset=" <<
Offset;
1688bool LSRUse::HasFormulaWithSameRegs(
const Formula &
F)
const {
1690 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1697float LSRUse::getNotSelectedProbability(
const SCEV *
Reg)
const {
1699 for (
const Formula &
F : Formulae)
1700 if (
F.referencesReg(
Reg))
1702 return ((
float)(Formulae.size() - FNum)) / Formulae.size();
1707bool LSRUse::InsertFormula(
const Formula &
F,
const Loop &L) {
1708 assert(
F.isCanonical(L) &&
"Invalid canonical representation");
1710 if (!Formulae.empty() && RigidFormula)
1714 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1722 assert((!
F.ScaledReg || !
F.ScaledReg->isZero()) &&
1723 "Zero allocated in a scaled register!");
1725 for (
const SCEV *BaseReg :
F.BaseRegs)
1726 assert(!
BaseReg->isZero() &&
"Zero allocated in a base register!");
1730 Formulae.push_back(
F);
1741void LSRUse::DeleteFormula(Formula &
F) {
1742 if (&
F != &Formulae.back())
1744 Formulae.pop_back();
1748void LSRUse::RecomputeRegs(
size_t LUIdx, RegUseTracker &RegUses) {
1750 SmallPtrSet<const SCEV *, 4> OldRegs = std::move(Regs);
1752 for (
const Formula &
F : Formulae) {
1753 if (
F.ScaledReg) Regs.
insert(
F.ScaledReg);
1758 for (
const SCEV *S : OldRegs)
1760 RegUses.dropRegister(S, LUIdx);
1763#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1764void LSRUse::print(raw_ostream &OS)
const {
1765 OS <<
"LSR Use: Kind=";
1767 case Basic: OS <<
"Basic";
break;
1768 case Special: OS <<
"Special";
break;
1769 case ICmpZero: OS <<
"ICmpZero";
break;
1771 OS <<
"Address of ";
1775 OS << *AccessTy.MemTy;
1778 OS <<
" in addrspace(" << AccessTy.AddrSpace <<
')';
1781 OS <<
", Offsets={";
1782 bool NeedComma =
false;
1783 for (
const LSRFixup &
Fixup : Fixups) {
1784 if (NeedComma) OS <<
',';
1790 if (AllFixupsOutsideLoop)
1791 OS <<
", all-fixups-outside-loop";
1793 if (AllFixupsUnconditional)
1794 OS <<
", all-fixups-unconditional";
1803 LSRUse::KindType Kind, MemAccessTy AccessTy,
1805 bool HasBaseReg, int64_t Scale,
1808 case LSRUse::Address: {
1809 int64_t FixedOffset =
1810 BaseOffset.isScalable() ? 0 : BaseOffset.getFixedValue();
1811 int64_t ScalableOffset =
1812 BaseOffset.isScalable() ? BaseOffset.getKnownMinValue() : 0;
1813 return TTI.isLegalAddressingMode(AccessTy.MemTy, BaseGV, FixedOffset,
1814 HasBaseReg, Scale, AccessTy.AddrSpace,
1815 Fixup, ScalableOffset);
1817 case LSRUse::ICmpZero:
1824 if (Scale != 0 && HasBaseReg && BaseOffset.isNonZero())
1829 if (Scale != 0 && Scale != -1)
1834 if (BaseOffset.isNonZero()) {
1837 if (BaseOffset.isScalable())
1847 BaseOffset = BaseOffset.getFixed(-(
uint64_t)BaseOffset.getFixedValue());
1848 return TTI.isLegalICmpImmediate(BaseOffset.getFixedValue());
1856 return !BaseGV && Scale == 0 && BaseOffset.isZero();
1858 case LSRUse::Special:
1860 return !BaseGV && (Scale == 0 || Scale == -1) && BaseOffset.isZero();
1867 Immediate MinOffset, Immediate MaxOffset,
1868 LSRUse::KindType Kind, MemAccessTy AccessTy,
1870 bool HasBaseReg, int64_t Scale) {
1871 if (BaseOffset.isNonZero() &&
1872 (BaseOffset.isScalable() != MinOffset.isScalable() ||
1873 BaseOffset.isScalable() != MaxOffset.isScalable()))
1876 int64_t
Base = BaseOffset.getKnownMinValue();
1877 int64_t Min = MinOffset.getKnownMinValue();
1878 int64_t Max = MaxOffset.getKnownMinValue();
1881 MinOffset = Immediate::get((
uint64_t)
Base + Min, MinOffset.isScalable());
1884 MaxOffset = Immediate::get((
uint64_t)
Base + Max, MaxOffset.isScalable());
1887 HasBaseReg, Scale) &&
1893 Immediate MinOffset, Immediate MaxOffset,
1894 LSRUse::KindType Kind, MemAccessTy AccessTy,
1895 const Formula &
F,
const Loop &L) {
1903 assert((
F.isCanonical(L) ||
F.Scale != 0));
1905 F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
F.Scale);
1910 Immediate MaxOffset, LSRUse::KindType Kind,
1912 Immediate BaseOffset,
bool HasBaseReg, int64_t Scale) {
1915 BaseOffset, HasBaseReg, Scale) ||
1920 BaseGV, BaseOffset,
true, 0));
1924 Immediate MaxOffset, LSRUse::KindType Kind,
1925 MemAccessTy AccessTy,
const Formula &
F) {
1926 return isLegalUse(
TTI, MinOffset, MaxOffset, Kind, AccessTy,
F.BaseGV,
1927 F.BaseOffset,
F.HasBaseReg,
F.Scale);
1933 return TTI.isLegalAddScalableImmediate(
Offset.getKnownMinValue());
1935 return TTI.isLegalAddImmediate(
Offset.getFixedValue());
1939 const LSRUse &LU,
const Formula &
F) {
1941 if (LU.Kind == LSRUse::Address &&
TTI.LSRWithInstrQueries()) {
1942 for (
const LSRFixup &
Fixup : LU.Fixups)
1944 (
F.BaseOffset +
Fixup.Offset),
F.HasBaseReg,
1945 F.Scale,
Fixup.UserInst))
1951 LU.AccessTy,
F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
1956 const LSRUse &LU,
const Formula &
F,
1965 return F.Scale != 1;
1968 case LSRUse::Address: {
1970 int64_t ScalableMin = 0, ScalableMax = 0, FixedMin = 0, FixedMax = 0;
1971 if (
F.BaseOffset.isScalable()) {
1972 ScalableMin = (
F.BaseOffset + LU.MinOffset).getKnownMinValue();
1973 ScalableMax = (
F.BaseOffset + LU.MaxOffset).getKnownMinValue();
1975 FixedMin = (
F.BaseOffset + LU.MinOffset).getFixedValue();
1976 FixedMax = (
F.BaseOffset + LU.MaxOffset).getFixedValue();
1980 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1983 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1986 "Legal addressing mode has an illegal cost!");
1987 return std::max(ScaleCostMinOffset, ScaleCostMaxOffset);
1989 case LSRUse::ICmpZero:
1991 case LSRUse::Special:
2002 LSRUse::KindType Kind, MemAccessTy AccessTy,
2006 if (BaseOffset.isZero() && !BaseGV)
2011 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2015 if (!HasBaseReg && Scale == 1) {
2025 if (HasBaseReg && BaseOffset.isNonZero() && Kind != LSRUse::ICmpZero &&
2027 Opts.lsr_drop_scaled_reg_for_vscale)
2037 Immediate MaxOffset, LSRUse::KindType Kind,
2038 MemAccessTy AccessTy,
const SCEV *S,
2041 if (S->
isZero())
return true;
2054 if (BaseOffset.isZero() && !BaseGV)
2057 if (BaseOffset.isScalable())
2062 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2065 BaseOffset, HasBaseReg, Scale);
2082 const SCEV *IncExpr;
2084 IVInc(Instruction *U,
Value *O,
const SCEV *
E)
2085 : UserInst(
U), IVOperand(
O), IncExpr(
E) {}
2092 const SCEV *ExprBase =
nullptr;
2094 IVChain() =
default;
2095 IVChain(
const IVInc &Head,
const SCEV *
Base)
2096 : Incs(1, Head), ExprBase(
Base) {}
2101 const_iterator
begin()
const {
2103 return std::next(Incs.
begin());
2105 const_iterator
end()
const {
2110 bool hasIncs()
const {
return Incs.
size() >= 2; }
2119 bool isProfitableIncrement(
const SCEV *OperExpr,
2120 const SCEV *IncExpr,
2128 SmallPtrSet<Instruction*, 4> FarUsers;
2129 SmallPtrSet<Instruction*, 4> NearUsers;
2134 const ScalarOptions &Opts;
2136 ScalarEvolution &SE;
2139 AssumptionCache &AC;
2140 TargetLibraryInfo &TLI;
2141 const TargetTransformInfo &
TTI;
2143 MemorySSAUpdater *MSSAU;
2147 bool HardwareLoopProfitable =
false;
2148 bool ShouldPreserveLCSSA =
false;
2162 SetVector<int64_t, SmallVector<int64_t, 8>, SmallSet<int64_t, 8>> Factors;
2169 SmallSetVector<Type *, 4> Types;
2175 RegUseTracker RegUses;
2180 static const unsigned MaxChains = 8;
2186 SmallPtrSet<Use*, MaxChains> IVIncSet;
2189 SmallVector<llvm::WeakVH, 2> ScalarEvolutionIVs;
2195 SmallSetVector<Instruction *, 4> InsertedNonLCSSAInsts;
2197 void OptimizeShadowIV();
2198 bool FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse);
2200 void OptimizeLoopTermCond();
2202 void ChainInstruction(Instruction *UserInst, Instruction *IVOper,
2203 SmallVectorImpl<ChainUsers> &ChainUsersVec);
2204 void FinalizeChain(IVChain &Chain);
2205 void CollectChains();
2206 void GenerateIVChain(
const IVChain &Chain,
2207 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2209 void CollectInterestingTypesAndFactors();
2210 void CollectFixupsAndInitialFormulae();
2213 using UseMapTy = DenseMap<LSRUse::SCEVUseKindPair, size_t>;
2216 bool reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
bool HasBaseReg,
2217 LSRUse::KindType Kind, MemAccessTy AccessTy);
2219 std::pair<size_t, Immediate> getUse(
const SCEV *&Expr, LSRUse::KindType Kind,
2220 MemAccessTy AccessTy);
2222 void DeleteUse(LSRUse &LU,
size_t LUIdx);
2224 LSRUse *FindUseWithSimilarFormula(
const Formula &
F,
const LSRUse &OrigLU);
2226 void InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2227 void InsertSupplementalFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2228 void CountRegisters(
const Formula &
F,
size_t LUIdx);
2229 bool InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F);
2230 bool IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const;
2232 void CollectLoopInvariantFixupsAndFormulae();
2234 void GenerateReassociations(LSRUse &LU,
unsigned LUIdx, Formula
Base,
2235 unsigned Depth = 0);
2237 void GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
2239 size_t Idx,
bool IsScaledReg =
false);
2240 void GenerateCombinations(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2241 void GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2242 const Formula &
Base,
size_t Idx,
2243 bool IsScaledReg =
false);
2244 void GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2245 void GenerateConstantOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2246 const Formula &
Base,
2247 const SmallVectorImpl<Immediate> &Worklist,
2248 size_t Idx,
bool IsScaledReg =
false);
2249 void GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2250 void GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2251 void GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2252 void GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2253 void GenerateCrossUseConstantOffsets();
2254 void GenerateAllReuseFormulae();
2256 void FilterOutUndesirableDedicatedRegisters();
2258 size_t EstimateSearchSpaceComplexity()
const;
2259 void NarrowSearchSpaceByDetectingSupersets();
2260 void NarrowSearchSpaceByCollapsingUnrolledCode();
2261 void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
2262 void NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
2263 void NarrowSearchSpaceByFilterPostInc();
2264 void NarrowSearchSpaceByMergingUsesOutsideLoop();
2265 void NarrowSearchSpaceByDeletingCostlyFormulas();
2266 void NarrowSearchSpaceByPickingWinnerRegs();
2267 void NarrowSearchSpaceUsingHeuristics();
2269 void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
2271 SmallVectorImpl<const Formula *> &Workspace,
2272 const Cost &CurCost,
2273 const SmallPtrSet<const SCEV *, 16> &CurRegs,
2274 DenseSet<const SCEV *> &VisitedRegs)
const;
2275 void Solve(SmallVectorImpl<const Formula *> &Solution)
const;
2279 const SmallVectorImpl<Instruction *> &Inputs)
const;
2282 const LSRUse &LU)
const;
2284 Value *Expand(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2286 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const;
2287 void RewriteForPHI(PHINode *PN,
const LSRUse &LU,
const LSRFixup &LF,
2289 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2290 void Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2291 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2292 void ImplementSolution(
const SmallVectorImpl<const Formula *> &Solution);
2299 LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
2300 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
2301 const TargetTransformInfo &
TTI, AssumptionCache &AC,
2302 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
2303 bool PreserveLCSSA);
2305 bool getChanged()
const {
return Changed; }
2306 const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs()
const {
2307 return ScalarEvolutionIVs;
2310 void print_factors_and_types(raw_ostream &OS)
const;
2311 void print_fixups(raw_ostream &OS)
const;
2312 void print_uses(raw_ostream &OS)
const;
2313 void print(raw_ostream &OS)
const;
2321void LSRInstance::OptimizeShadowIV() {
2331 Type *DestTy =
nullptr;
2332 bool IsSigned =
false;
2348 DestTy = UCast->getDestTy();
2352 DestTy = SCast->getDestTy();
2354 if (!DestTy)
continue;
2374 if (Mantissa == -1)
continue;
2378 unsigned Entry, Latch;
2388 if (!Init)
continue;
2389 Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
2393 BinaryOperator *Incr =
2395 if (!Incr)
continue;
2396 if (Incr->
getOpcode() != Instruction::Add
2397 && Incr->
getOpcode() != Instruction::Sub)
2401 ConstantInt *
C =
nullptr;
2413 if (!
C->getValue().isStrictlyPositive())
2421 Constant *CFP = ConstantFP::get(DestTy,
C->getZExtValue());
2423 Incr->
getOpcode() == Instruction::Add ? Instruction::FAdd
2424 : Instruction::FSub,
2441bool LSRInstance::FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse) {
2442 for (IVStrideUse &U : IU)
2443 if (
U.getUser() ==
Cond) {
2501Instruction *LSRInstance::OptimizeMax(ICmpInst *
Cond, IVStrideUse *&CondUse) {
2516 const SCEV *IterationCount = SE.
getAddExpr(One, BackedgeTakenCount);
2517 if (IterationCount != SE.
getSCEV(Sel))
return Cond;
2523 const SCEVNAryExpr *
Max =
nullptr;
2525 Pred = ICmpInst::ICMP_SLE;
2528 Pred = ICmpInst::ICMP_SLT;
2531 Pred = ICmpInst::ICMP_ULT;
2540 if (
Max->getNumOperands() != 2)
2543 const SCEV *MaxLHS =
Max->getOperand(0);
2544 const SCEV *MaxRHS =
Max->getOperand(1);
2549 (ICmpInst::isTrueWhenEqual(Pred) ? !MaxLHS->
isZero() : (MaxLHS != One)))
2560 "Loop condition operand is an addrec in a different loop!");
2564 Value *NewRHS =
nullptr;
2565 if (ICmpInst::isTrueWhenEqual(Pred)) {
2569 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2570 NewRHS = BO->getOperand(0);
2573 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2574 NewRHS = BO->getOperand(0);
2582 NewRHS = SU->getValue();
2594 ICmpInst *NewCond =
new ICmpInst(
Cond->getIterator(), Pred,
2595 Cond->getOperand(0), NewRHS,
"scmp");
2599 Cond->replaceAllUsesWith(NewCond);
2602 Cond->eraseFromParent();
2604 if (
Cmp->use_empty()) {
2606 Cmp->eraseFromParent();
2613LSRInstance::OptimizeLoopTermCond() {
2614 SmallPtrSet<Instruction *, 4> PostIncs;
2629 SmallVector<BasicBlock*, 8> ExitingBlocks;
2630 L->getExitingBlocks(ExitingBlocks);
2638 for (BasicBlock *ExitingBlock : ExitingBlocks) {
2660 IVStrideUse *CondUse =
nullptr;
2661 if (!FindIVUserForCond(
Cond, CondUse))
2671 Cond = OptimizeMax(Cmp, CondUse);
2676 if (!DT.
dominates(ExitingBlock, LatchBlock))
2681 if (LatchBlock != ExitingBlock)
2682 for (
const IVStrideUse &UI : IU)
2685 if (&UI != CondUse &&
2689 const SCEV *
A = IU.getStride(*CondUse, L);
2690 const SCEV *
B = IU.getStride(UI, L);
2691 if (!
A || !
B)
continue;
2700 if (
const SCEVConstant *
D =
2702 const ConstantInt *
C =
D->getValue();
2704 if (
C->isOne() ||
C->isMinusOne())
2705 goto decline_post_inc;
2707 if (
C->getValue().getSignificantBits() >= 64 ||
2708 C->getValue().isMinSignedValue())
2709 goto decline_post_inc;
2712 MemAccessTy AccessTy =
2714 int64_t Scale =
C->getSExtValue();
2718 AccessTy.AddrSpace))
2719 goto decline_post_inc;
2724 AccessTy.AddrSpace))
2725 goto decline_post_inc;
2730 LLVM_DEBUG(
dbgs() <<
" Change loop exiting icmp to use postinc iv: "
2738 if (
Cond->hasOneUse()) {
2744 Cond->setName(
L->getHeader()->getName() +
".termcond");
2766 IVIncInsertPos =
L->getLoopLatch()->getTerminator();
2767 for (Instruction *Inst : PostIncs)
2773bool LSRInstance::reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
2774 bool HasBaseReg, LSRUse::KindType Kind,
2775 MemAccessTy AccessTy) {
2776 Immediate NewMinOffset = LU.MinOffset;
2777 Immediate NewMaxOffset = LU.MaxOffset;
2778 MemAccessTy NewAccessTy = AccessTy;
2783 if (LU.Kind != Kind)
2789 if (Kind == LSRUse::Address) {
2790 if (AccessTy.MemTy != LU.AccessTy.MemTy) {
2791 NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->
getContext(),
2792 AccessTy.AddrSpace);
2797 if (Immediate::isKnownLT(NewOffset, LU.MinOffset)) {
2799 LU.MaxOffset - NewOffset, HasBaseReg))
2801 NewMinOffset = NewOffset;
2802 }
else if (Immediate::isKnownGT(NewOffset, LU.MaxOffset)) {
2804 NewOffset - LU.MinOffset, HasBaseReg))
2806 NewMaxOffset = NewOffset;
2812 if (NewAccessTy.MemTy && NewAccessTy.MemTy->
isVoidTy() &&
2813 (NewMinOffset.isScalable() || NewMaxOffset.isScalable()))
2817 LU.MinOffset = NewMinOffset;
2818 LU.MaxOffset = NewMaxOffset;
2819 LU.AccessTy = NewAccessTy;
2826std::pair<size_t, Immediate> LSRInstance::getUse(
const SCEV *&Expr,
2827 LSRUse::KindType Kind,
2828 MemAccessTy AccessTy) {
2829 const SCEV *
Copy = Expr;
2832 Opts, ExprUse, SE, AccessTy.MemTy && AccessTy.MemTy->
isScalableTy());
2839 Offset = Immediate::getFixed(0);
2842 std::pair<UseMapTy::iterator, bool>
P =
2843 UseMap.
try_emplace(LSRUse::SCEVUseKindPair(Expr, Kind));
2846 size_t LUIdx =
P.first->second;
2847 LSRUse &LU =
Uses[LUIdx];
2848 if (reconcileNewOffset(LU,
Offset,
true, Kind, AccessTy))
2850 return std::make_pair(LUIdx,
Offset);
2854 size_t LUIdx =
Uses.size();
2855 P.first->second = LUIdx;
2856 Uses.push_back(LSRUse(Kind, AccessTy));
2857 LSRUse &LU =
Uses[LUIdx];
2861 return std::make_pair(LUIdx,
Offset);
2865void LSRInstance::DeleteUse(LSRUse &LU,
size_t LUIdx) {
2866 if (&LU != &
Uses.back())
2871 RegUses.swapAndDropUse(LUIdx,
Uses.size());
2877LSRInstance::FindUseWithSimilarFormula(
const Formula &OrigF,
2878 const LSRUse &OrigLU) {
2880 for (LSRUse &LU :
Uses) {
2886 if (&LU != &OrigLU && LU.Kind != LSRUse::ICmpZero &&
2887 LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
2888 LU.HasFormulaWithSameRegs(OrigF)) {
2890 for (
const Formula &
F : LU.Formulae) {
2893 if (
F.BaseRegs == OrigF.BaseRegs &&
2894 F.ScaledReg == OrigF.ScaledReg &&
2895 F.BaseGV == OrigF.BaseGV &&
2896 F.Scale == OrigF.Scale &&
2897 F.UnfoldedOffset == OrigF.UnfoldedOffset) {
2898 if (
F.BaseOffset.isZero())
2913void LSRInstance::CollectInterestingTypesAndFactors() {
2914 SmallSetVector<const SCEV *, 4> Strides;
2918 for (
const IVStrideUse &U : IU) {
2919 const SCEV *Expr = IU.getExpr(U);
2937 }
while (!Worklist.
empty());
2941 for (SmallSetVector<const SCEV *, 4>::const_iterator
2943 for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
2944 std::next(
I); NewStrideIter !=
E; ++NewStrideIter) {
2945 const SCEV *OldStride = *
I;
2946 const SCEV *NewStride = *NewStrideIter;
2956 if (
const SCEVConstant *Factor =
2959 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
2960 Factors.insert(Factor->getAPInt().getSExtValue());
2961 }
else if (
const SCEVConstant *Factor =
2965 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
2966 Factors.insert(Factor->getAPInt().getSExtValue());
2972 if (Types.size() == 1)
2984 for(; OI != OE; ++OI) {
3003 return Trunc->getOperand(0);
3036 if (SubExpr->getSCEVType() ==
scAddExpr)
3039 if (SubExpr->getSCEVType() !=
scMulExpr)
3055bool IVChain::isProfitableIncrement(
const SCEV *OperExpr,
3056 const SCEV *IncExpr,
3057 ScalarEvolution &SE) {
3070 SmallPtrSet<const SCEV*, 8> Processed;
3091 if (!Chain.hasIncs())
3094 if (!
Users.empty()) {
3095 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" users:\n";
3097 :
Users) {
dbgs() <<
" " << *Inst <<
"\n"; });
3100 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3109 && SE.
getSCEV(Chain.tailUserInst()) == Chain.Incs[0].IncExpr) {
3112 const SCEV *LastIncExpr =
nullptr;
3113 unsigned NumConstIncrements = 0;
3114 unsigned NumVarIncrements = 0;
3115 unsigned NumReusedIncrements = 0;
3117 if (
TTI.isProfitableLSRChainElement(Chain.Incs[0].UserInst))
3120 for (
const IVInc &Inc : Chain) {
3121 if (
TTI.isProfitableLSRChainElement(Inc.UserInst))
3123 if (Inc.IncExpr->isZero())
3129 ++NumConstIncrements;
3133 if (Inc.IncExpr == LastIncExpr)
3134 ++NumReusedIncrements;
3138 LastIncExpr = Inc.IncExpr;
3143 if (NumConstIncrements > 1)
3150 cost += NumVarIncrements;
3154 cost -= NumReusedIncrements;
3156 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" Cost: " << cost
3163void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
3164 SmallVectorImpl<ChainUsers> &ChainUsersVec) {
3168 const SCEV *
const OperExpr = SE.
getSCEV(NextIV);
3169 const SCEV *
const OperExprBase =
getExprBase(OperExpr);
3173 unsigned ChainIdx = 0, NChains = IVChainVec.size();
3174 const SCEV *LastIncExpr =
nullptr;
3175 for (; ChainIdx < NChains; ++ChainIdx) {
3176 IVChain &Chain = IVChainVec[ChainIdx];
3194 const SCEV *PrevExpr = SE.
getSCEV(PrevIV);
3195 const SCEV *IncExpr = SE.
getMinusSCEV(OperExpr, PrevExpr);
3199 if (Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
3200 LastIncExpr = IncExpr;
3206 if (ChainIdx == NChains) {
3213 LastIncExpr = OperExpr;
3220 IVChainVec.push_back(IVChain(IVInc(UserInst, IVOper, LastIncExpr),
3222 ChainUsersVec.
resize(NChains);
3223 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Head: (" << *UserInst
3224 <<
") IV=" << *LastIncExpr <<
"\n");
3226 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Inc: (" << *UserInst
3227 <<
") IV+" << *LastIncExpr <<
"\n");
3229 IVChainVec[ChainIdx].add(IVInc(UserInst, IVOper, LastIncExpr));
3231 IVChain &Chain = IVChainVec[ChainIdx];
3233 SmallPtrSet<Instruction*,4> &NearUsers = ChainUsersVec[ChainIdx].NearUsers;
3235 if (!LastIncExpr->
isZero()) {
3236 ChainUsersVec[ChainIdx].FarUsers.insert_range(NearUsers);
3245 for (User *U : IVOper->
users()) {
3251 IVChain::const_iterator IncIter = Chain.Incs.begin();
3252 IVChain::const_iterator IncEnd = Chain.Incs.end();
3253 for( ; IncIter != IncEnd; ++IncIter) {
3254 if (IncIter->UserInst == OtherUse)
3257 if (IncIter != IncEnd)
3262 && IU.isIVUserOrOperand(OtherUse)) {
3265 NearUsers.
insert(OtherUse);
3270 ChainUsersVec[ChainIdx].FarUsers.
erase(UserInst);
3295void LSRInstance::CollectChains() {
3299 SmallVector<BasicBlock *,8> LatchPath;
3302 Rung->
getBlock() != LoopHeader; Rung = Rung->getIDom()) {
3308 for (BasicBlock *BB :
reverse(LatchPath)) {
3309 for (Instruction &
I : *BB) {
3315 if (IU.isEphemeral(&
I))
3325 for (
unsigned ChainIdx = 0, NChains = IVChainVec.size();
3326 ChainIdx < NChains; ++ChainIdx) {
3327 ChainUsersVec[ChainIdx].NearUsers.
erase(&
I);
3330 SmallPtrSet<Instruction*, 4> UniqueOperands;
3333 while (IVOpIter != IVOpEnd) {
3335 if (UniqueOperands.
insert(IVOpInst).second)
3336 ChainInstruction(&
I, IVOpInst, ChainUsersVec);
3337 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3342 for (PHINode &PN :
L->getHeader()->phis()) {
3349 ChainInstruction(&PN, IncV, ChainUsersVec);
3352 unsigned ChainIdx = 0;
3353 for (
unsigned UsersIdx = 0, NChains = IVChainVec.size();
3354 UsersIdx < NChains; ++UsersIdx) {
3356 ChainUsersVec[UsersIdx].FarUsers, SE,
TTI))
3359 if (ChainIdx != UsersIdx)
3360 IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
3361 FinalizeChain(IVChainVec[ChainIdx]);
3364 IVChainVec.resize(ChainIdx);
3367void LSRInstance::FinalizeChain(IVChain &Chain) {
3368 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3369 LLVM_DEBUG(
dbgs() <<
"Final Chain: " << *Chain.Incs[0].UserInst <<
"\n");
3371 for (
const IVInc &Inc : Chain) {
3373 auto UseI =
find(Inc.UserInst->operands(), Inc.IVOperand);
3374 assert(UseI != Inc.UserInst->op_end() &&
"cannot find IV operand");
3375 IVIncSet.insert(UseI);
3384 Immediate IncOffset = Immediate::getZero();
3393 C->getSignificantBits() > 64)
3395 IncOffset = Immediate::getScalable(
C->getSExtValue());
3403 nullptr, IncOffset,
false))
3411void LSRInstance::GenerateIVChain(
const IVChain &Chain,
3412 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
3415 const IVInc &Head = Chain.Incs[0];
3420 Value *IVSrc =
nullptr;
3421 while (IVOpIter != IVOpEnd) {
3432 if (SE.
getSCEV(*IVOpIter) == Head.IncExpr
3433 || SE.
getSCEV(IVSrc) == Head.IncExpr) {
3436 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3438 if (IVOpIter == IVOpEnd) {
3440 LLVM_DEBUG(
dbgs() <<
"Concealed chain head: " << *Head.UserInst <<
"\n");
3443 assert(IVSrc &&
"Failed to find IV chain source");
3448 const SCEV *LeftOverExpr =
nullptr;
3449 const SCEV *Accum = SE.
getZero(IntTy);
3453 for (
const IVInc &Inc : Chain) {
3456 InsertPt =
L->getLoopLatch()->getTerminator();
3460 Value *IVOper = IVSrc;
3461 if (!Inc.IncExpr->isZero()) {
3466 LeftOverExpr = LeftOverExpr
3472 bool FoundBase =
false;
3473 for (
auto [MapScev, MapIVOper] :
reverse(Bases)) {
3474 const SCEV *Remainder = SE.
getMinusSCEV(Accum, MapScev);
3476 if (!Remainder->
isZero()) {
3478 Value *IncV =
Rewriter.expandCodeFor(Remainder, IntTy, InsertPt);
3479 const SCEV *IVOperExpr =
3481 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3490 if (!FoundBase && LeftOverExpr && !LeftOverExpr->
isZero()) {
3493 Value *IncV =
Rewriter.expandCodeFor(LeftOverExpr, IntTy, InsertPt);
3496 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3501 assert(IVTy == IVOper->
getType() &&
"inconsistent IV increment type");
3504 LeftOverExpr =
nullptr;
3508 if (IVTy != OperTy) {
3510 "cannot extend a chained IV");
3512 IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy,
"lsr.chain");
3514 Inc.UserInst->replaceUsesOfWith(Inc.IVOperand, IVOper);
3521 for (PHINode &Phi :
L->getHeader()->phis()) {
3525 Phi.getIncomingValueForBlock(
L->getLoopLatch()));
3528 Value *IVOper = IVSrc;
3530 if (IVTy != PostIncTy) {
3532 IRBuilder<> Builder(
L->getLoopLatch()->getTerminator());
3533 Builder.SetCurrentDebugLocation(PostIncV->
getDebugLoc());
3534 IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy,
"lsr.chain");
3536 Phi.replaceUsesOfWith(PostIncV, IVOper);
3542void LSRInstance::CollectFixupsAndInitialFormulae() {
3543 CondBrInst *ExitBranch =
nullptr;
3544 bool SaveCmp =
TTI.
canSaveCmp(L, &ExitBranch, &SE, &LI, &DT, &AC, &TLI);
3547 SmallPtrSet<const SCEV *, 16> Regs;
3548 DenseSet<const SCEV *> VisitedRegs;
3549 DenseSet<size_t> VisitedLSRUse;
3551 for (
const IVStrideUse &U : IU) {
3556 assert(UseI != UserInst->
op_end() &&
"cannot find IV operand");
3557 if (IVIncSet.count(UseI)) {
3558 LLVM_DEBUG(
dbgs() <<
"Use is in profitable chain: " << **UseI <<
'\n');
3562 LSRUse::KindType
Kind = LSRUse::Basic;
3563 MemAccessTy AccessTy;
3565 Kind = LSRUse::Address;
3569 const SCEV *S = IU.getExpr(U);
3585 if (CI->isEquality()) {
3588 Value *
NV = CI->getOperand(1);
3589 if (NV ==
U.getOperandValToReplace()) {
3590 CI->setOperand(1, CI->getOperand(0));
3591 CI->setOperand(0, NV);
3592 NV = CI->getOperand(1);
3599 (!
NV->getType()->isPointerTy() ||
3606 Kind = LSRUse::ICmpZero;
3608 }
else if (
L->isLoopInvariant(NV) &&
3611 !
NV->getType()->isPointerTy()) {
3622 Kind = LSRUse::ICmpZero;
3629 for (
size_t i = 0, e = Factors.size(); i != e; ++i)
3630 if (Factors[i] != -1)
3631 Factors.insert(-(
uint64_t)Factors[i]);
3637 std::pair<size_t, Immediate>
P = getUse(S, Kind, AccessTy);
3638 size_t LUIdx =
P.first;
3640 LSRUse &LU =
Uses[LUIdx];
3643 LSRFixup &LF = LU.getNewFixup();
3644 LF.UserInst = UserInst;
3645 LF.OperandValToReplace =
U.getOperandValToReplace();
3646 LF.PostIncLoops = TmpPostIncLoops;
3648 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3649 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3652 if (!VisitedLSRUse.
count(LUIdx) && !LF.isUseFullyOutsideLoop(L)) {
3654 F.initialMatch(S, L, SE);
3655 BaselineCost.RateFormula(
F, Regs, VisitedRegs, LU,
3656 HardwareLoopProfitable);
3657 VisitedLSRUse.
insert(LUIdx);
3661 if (LU.Formulae.empty()) {
3662 InsertInitialFormula(S, LU, LUIdx);
3663 CountRegisters(LU.Formulae.back(), LUIdx);
3672void LSRInstance::InsertInitialFormula(
const SCEV *S, LSRUse &LU,
3676 LU.RigidFormula =
true;
3679 F.initialMatch(S, L, SE);
3680 bool Inserted = InsertFormula(LU, LUIdx,
F);
3681 assert(Inserted &&
"Initial formula already exists!"); (void)Inserted;
3687LSRInstance::InsertSupplementalFormula(
const SCEV *S,
3688 LSRUse &LU,
size_t LUIdx) {
3690 F.BaseRegs.push_back(S);
3691 F.HasBaseReg =
true;
3692 bool Inserted = InsertFormula(LU, LUIdx,
F);
3693 assert(Inserted &&
"Supplemental formula already exists!"); (void)Inserted;
3697void LSRInstance::CountRegisters(
const Formula &
F,
size_t LUIdx) {
3699 RegUses.countRegister(
F.ScaledReg, LUIdx);
3700 for (
const SCEV *BaseReg :
F.BaseRegs)
3701 RegUses.countRegister(BaseReg, LUIdx);
3706bool LSRInstance::InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F) {
3709 "Formula is illegal");
3711 if (!LU.InsertFormula(
F, *L))
3714 CountRegisters(
F, LUIdx);
3720bool LSRInstance::IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const {
3732LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
3734 SmallPtrSet<const SCEV *, 32> Visited;
3741 while (!Worklist.
empty()) {
3745 if (!Visited.
insert(S).second)
3756 const Value *
V = US->getValue();
3759 if (
L->contains(Inst))
continue;
3763 for (
const Use &U :
V->uses()) {
3773 if (UserInst->
getParent()->getParent() !=
L->getHeader()->getParent())
3795 bool HasIncompatibleEHPTerminatedBlock =
false;
3797 for (
unsigned int I = 0;
I < PhiNode->getNumIncomingValues();
I++) {
3798 if (PhiNode->getIncomingValue(
I) == ExpectedValue) {
3799 if (PhiNode->getIncomingBlock(
I)->getTerminator()->isEHPad()) {
3800 HasIncompatibleEHPTerminatedBlock =
true;
3805 if (HasIncompatibleEHPTerminatedBlock) {
3828 unsigned OtherIdx = !
U.getOperandNo();
3829 Value *OtherOp = ICI->getOperand(OtherIdx);
3839 std::pair<size_t, Immediate>
P =
3840 getUse(S, LSRUse::Basic, MemAccessTy());
3841 size_t LUIdx =
P.first;
3843 LSRUse &LU =
Uses[LUIdx];
3844 LSRFixup &LF = LU.getNewFixup();
3845 LF.UserInst =
const_cast<Instruction *
>(UserInst);
3846 LF.OperandValToReplace =
U;
3848 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3849 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3850 InsertSupplementalFormula(US, LU, LUIdx);
3851 CountRegisters(LU.Formulae.back(),
Uses.size() - 1);
3867 unsigned Depth = 0) {
3874 for (
const SCEV *S :
Add->operands()) {
3881 const SCEV *Start, *Step;
3886 if (Start->isZero())
3895 Remainder =
nullptr;
3897 if (Remainder != Start) {
3919 LSRUse &LU,
const SCEV *S,
const Loop *L,
3921 if (LU.Kind != LSRUse::Address ||
3922 !LU.AccessTy.getType()->isIntOrIntVectorTy())
3928 if (
TTI.isIndexedLoadLegal(
TTI.MIM_PostInc, S->
getType()) ||
3937void LSRInstance::GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
3938 const Formula &
Base,
3939 unsigned Depth,
size_t Idx,
3949 const SCEV *Remainder =
CollectSubexprs(BaseReg,
nullptr, AddOps, L, SE);
3953 if (AddOps.
size() == 1)
3967 LU.AccessTy, *J,
Base.getNumRegs() > 1))
3972 InnerAddOps.append(std::next(J), std::as_const(AddOps).
end());
3976 if (InnerAddOps.size() == 1 &&
3978 LU.AccessTy, InnerAddOps[0],
Base.getNumRegs() > 1))
3981 const SCEV *InnerSum = SE.
getAddExpr(InnerAddOps);
3986 if (
F.UnfoldedOffset.isNonZero() &&
F.UnfoldedOffset.isScalable())
3995 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
3998 F.ScaledReg =
nullptr;
4001 F.BaseRegs.erase(
F.BaseRegs.begin() + Idx);
4002 }
else if (IsScaledReg)
4003 F.ScaledReg = InnerSum;
4005 F.BaseRegs[
Idx] = InnerSum;
4013 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
4016 F.BaseRegs.push_back(*J);
4021 if (InsertFormula(LU, LUIdx,
F))
4028 GenerateReassociations(LU, LUIdx, LU.Formulae.back(),
4034void LSRInstance::GenerateReassociations(LSRUse &LU,
unsigned LUIdx,
4036 assert(
Base.isCanonical(*L) &&
"Input must be in the canonical form");
4041 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4042 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth, i);
4044 if (
Base.Scale == 1)
4045 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth,
4051void LSRInstance::GenerateCombinations(LSRUse &LU,
unsigned LUIdx,
4054 if (
Base.BaseRegs.size() + (
Base.Scale == 1) +
4055 (
Base.UnfoldedOffset.isNonZero()) <=
4063 Formula NewBase =
Base;
4064 NewBase.BaseRegs.clear();
4065 Type *CombinedIntegerType =
nullptr;
4066 for (
const SCEV *BaseReg :
Base.BaseRegs) {
4069 if (!CombinedIntegerType)
4071 Ops.push_back(BaseReg);
4074 NewBase.BaseRegs.push_back(BaseReg);
4078 if (
Ops.size() == 0)
4083 auto GenerateFormula = [&](
const SCEV *Sum) {
4084 Formula
F = NewBase;
4092 F.BaseRegs.push_back(Sum);
4094 (void)InsertFormula(LU, LUIdx,
F);
4098 if (
Ops.size() > 1) {
4105 if (NewBase.UnfoldedOffset.isNonZero() && NewBase.UnfoldedOffset.isFixed()) {
4106 assert(CombinedIntegerType &&
"Missing a type for the unfolded offset");
4108 NewBase.UnfoldedOffset.getFixedValue(),
true));
4109 NewBase.UnfoldedOffset = Immediate::getFixed(0);
4115void LSRInstance::GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
4116 const Formula &
Base,
size_t Idx,
4120 if (
G->isZero() || !GV)
4124 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4129 F.BaseRegs[
Idx] =
G;
4130 (void)InsertFormula(LU, LUIdx,
F);
4134void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx,
4137 if (
Base.BaseGV)
return;
4139 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4140 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, i);
4141 if (
Base.Scale == 1)
4142 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, -1,
4147void LSRInstance::GenerateConstantOffsetsImpl(
4148 LSRUse &LU,
unsigned LUIdx,
const Formula &
Base,
4149 const SmallVectorImpl<Immediate> &Worklist,
size_t Idx,
bool IsScaledReg) {
4151 auto GenerateOffset = [&](
const SCEV *
G, Immediate
Offset) {
4153 if (!
Base.BaseOffset.isCompatibleImmediate(
Offset))
4155 F.BaseOffset =
Base.BaseOffset.subUnsigned(
Offset);
4157 if (
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F)) {
4159 const SCEV *NewOffset =
Offset.getSCEV(SE,
G->getType());
4165 F.ScaledReg =
nullptr;
4167 F.deleteBaseReg(
F.BaseRegs[Idx]);
4169 }
else if (IsScaledReg)
4172 F.BaseRegs[
Idx] = NewG;
4174 (void)InsertFormula(LU, LUIdx,
F);
4189 const APInt *StepInt;
4194 for (Immediate
Offset : Worklist) {
4196 Offset = Immediate::getFixed(
Offset.getFixedValue() - Step);
4202 for (Immediate
Offset : Worklist)
4209 if (
G->isZero() ||
Imm.isZero() ||
4210 !
Base.BaseOffset.isCompatibleImmediate(
Imm))
4213 F.BaseOffset =
F.BaseOffset.addUnsigned(
Imm);
4214 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4219 F.BaseRegs[
Idx] =
G;
4224 (void)InsertFormula(LU, LUIdx,
F);
4228void LSRInstance::GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx,
4234 if (LU.MaxOffset != LU.MinOffset)
4237 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4238 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, i);
4239 if (
Base.Scale == 1)
4240 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, -1,
4246void LSRInstance::GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx,
4248 if (LU.Kind != LSRUse::ICmpZero)
return;
4256 if (LU.MinOffset != LU.MaxOffset)
return;
4259 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4261 for (
const SCEV *BaseReg :
Base.BaseRegs)
4262 if (
BaseReg->getType()->isPointerTy())
4264 assert(!
Base.BaseGV &&
"ICmpZero use is not legal!");
4267 for (int64_t Factor : Factors) {
4272 if (
Base.BaseOffset.isMin() && Factor == -1)
4275 if (
Base.BaseOffset.isNonZero() &&
Base.BaseOffset.isScalable())
4277 Immediate NewBaseOffset =
Base.BaseOffset.mulUnsigned(Factor);
4278 assert(Factor != 0 &&
"Zero factor not expected!");
4279 if (NewBaseOffset.getFixedValue() / Factor !=
4280 Base.BaseOffset.getFixedValue())
4288 Immediate
Offset = LU.MinOffset;
4289 if (
Offset.isMin() && Factor == -1)
4292 if (
Offset.getFixedValue() / Factor != LU.MinOffset.getFixedValue())
4300 F.BaseOffset = NewBaseOffset;
4307 F.BaseOffset =
F.BaseOffset.addUnsigned(
Offset).subUnsigned(LU.MinOffset);
4309 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4312 for (
size_t i = 0, e =
F.BaseRegs.size(); i != e; ++i) {
4326 if (
F.UnfoldedOffset.isNonZero()) {
4327 if (
F.UnfoldedOffset.isMin() && Factor == -1)
4329 F.UnfoldedOffset =
F.UnfoldedOffset.mulUnsigned(Factor);
4330 if (
F.UnfoldedOffset.getFixedValue() / Factor !=
4331 Base.UnfoldedOffset.getFixedValue())
4335 IntTy,
F.UnfoldedOffset.getFixedValue()))
4340 (void)InsertFormula(LU, LUIdx,
F);
4347void LSRInstance::GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4354 if (
Base.Scale != 0 && !
Base.unscale())
4357 assert(
Base.Scale == 0 &&
"unscale did not did its job!");
4360 for (int64_t Factor : Factors) {
4361 Base.Scale = Factor;
4362 Base.HasBaseReg =
Base.BaseRegs.size() > 1;
4364 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4368 if (LU.Kind == LSRUse::Basic &&
4369 isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
4370 LU.AccessTy,
Base) &&
4371 LU.AllFixupsOutsideLoop)
4372 LU.Kind = LSRUse::Special;
4378 if (LU.Kind == LSRUse::ICmpZero && !
Base.HasBaseReg &&
4379 Base.BaseOffset.isZero() && !
Base.BaseGV)
4382 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i) {
4384 if (AR && (AR->
getLoop() == L || LU.AllFixupsOutsideLoop)) {
4385 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4390 if (
const SCEV *Quotient =
getExactSDiv(AR, FactorS, SE,
true))
4391 if (!Quotient->isZero()) {
4394 F.ScaledReg = Quotient;
4395 F.deleteBaseReg(
F.BaseRegs[i]);
4399 if (
F.Scale == 1 && (
F.BaseRegs.empty() ||
4400 (AR->
getLoop() != L && LU.AllFixupsOutsideLoop)))
4404 if (
F.Scale == 1 && LU.AllFixupsOutsideLoop)
4406 (void)InsertFormula(LU, LUIdx,
F);
4422 const SCEV *Result =
nullptr;
4423 for (
auto &L :
Loops) {
4427 if (!New || (Result && New != Result))
4432 assert(Result &&
"failed to create expression");
4437void LSRInstance::GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4439 if (
Base.BaseGV)
return;
4449 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4452 [](
const SCEV *S) { return S->getType()->isPointerTy(); }))
4456 for (
auto &LF : LU.Fixups)
4457 Loops.push_back(LF.PostIncLoops);
4459 for (
Type *SrcTy : Types) {
4468 const SCEV *NewScaledReg =
4470 if (!NewScaledReg || NewScaledReg->
isZero())
4472 F.ScaledReg = NewScaledReg;
4474 bool HasZeroBaseReg =
false;
4475 for (
const SCEV *&BaseReg :
F.BaseRegs) {
4476 const SCEV *NewBaseReg =
4478 if (!NewBaseReg || NewBaseReg->
isZero()) {
4479 HasZeroBaseReg =
true;
4489 if (!
F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
4493 (void)InsertFormula(LU, LUIdx,
F);
4506 const SCEV *OrigReg;
4508 WorkItem(
size_t LI, Immediate
I,
const SCEV *R)
4509 : LUIdx(LI),
Imm(
I), OrigReg(
R) {}
4511 void print(raw_ostream &OS)
const;
4517#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4518void WorkItem::print(raw_ostream &OS)
const {
4519 OS <<
"in formulae referencing " << *OrigReg <<
" in use " << LUIdx
4520 <<
" , add offset " <<
Imm;
4530void LSRInstance::GenerateCrossUseConstantOffsets() {
4532 using ImmMapTy = std::map<Immediate, const SCEV *, KeyOrderTargetImmediate>;
4534 DenseMap<const SCEV *, ImmMapTy>
Map;
4535 DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
4537 for (
const SCEV *Use : RegUses) {
4541 auto Pair =
Map.try_emplace(
Reg);
4544 Pair.first->second.insert(std::make_pair(
Imm, Use));
4545 UsedByIndicesMap[
Reg] |= RegUses.getUsedByIndices(Use);
4552 SmallSet<std::pair<size_t, Immediate>, 32, KeyOrderSizeTAndImmediate>
4554 for (
const SCEV *
Reg : Sequence) {
4555 const ImmMapTy &Imms =
Map.find(
Reg)->second;
4558 if (Imms.size() == 1)
4562 for (
const auto &Entry
4564 <<
' ' <<
Entry.first;
4568 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
4570 const SCEV *OrigReg = J->second;
4572 Immediate JImm = J->first;
4573 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
4576 UsedByIndicesMap[
Reg].
count() == 1) {
4584 Immediate
First = Imms.begin()->first;
4585 Immediate
Last = std::prev(Imms.end())->first;
4586 if (!
First.isCompatibleImmediate(
Last)) {
4593 bool Scalable =
First.isScalable() ||
Last.isScalable();
4594 int64_t FI =
First.getKnownMinValue();
4595 int64_t LI =
Last.getKnownMinValue();
4598 int64_t Avg = (FI & LI) + ((FI ^ LI) >> 1);
4601 Avg = Avg + ((FI ^ LI) & ((
uint64_t)Avg >> 63));
4602 ImmMapTy::const_iterator OtherImms[] = {
4603 Imms.begin(), std::prev(Imms.end()),
4604 Imms.lower_bound(Immediate::get(Avg, Scalable))};
4605 for (
const auto &M : OtherImms) {
4606 if (M == J || M == JE)
continue;
4607 if (!JImm.isCompatibleImmediate(
M->first))
4611 Immediate
Imm = JImm.subUnsigned(
M->first);
4612 for (
unsigned LUIdx : UsedByIndices.
set_bits())
4614 if (UniqueItems.
insert(std::make_pair(LUIdx,
Imm)).second)
4622 UsedByIndicesMap.
clear();
4623 UniqueItems.
clear();
4626 for (
const WorkItem &WI : WorkItems) {
4627 size_t LUIdx = WI.LUIdx;
4628 LSRUse &LU =
Uses[LUIdx];
4629 Immediate
Imm = WI.Imm;
4630 const SCEV *OrigReg = WI.OrigReg;
4633 const SCEV *NegImmS =
Imm.getNegativeSCEV(SE, IntTy);
4637 for (
size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
4638 Formula
F = LU.Formulae[
L];
4645 if (
F.ScaledReg == OrigReg) {
4646 if (!
F.BaseOffset.isCompatibleImmediate(
Imm))
4648 Immediate
Offset =
F.BaseOffset.addUnsigned(
Imm.mulUnsigned(
F.Scale));
4650 const SCEV *S =
Offset.getNegativeSCEV(SE, IntTy);
4651 if (
F.referencesReg(S))
4654 NewF.BaseOffset =
Offset;
4655 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4658 NewF.ScaledReg = SE.
getAddExpr(NegImmS, NewF.ScaledReg);
4667 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4669 if (
C->getValue()->isNegative() !=
4670 (NewF.BaseOffset.isLessThanZero()) &&
4671 (
C->getAPInt().abs() * APInt(
BitWidth,
F.Scale))
4672 .ule(std::abs(NewF.BaseOffset.getFixedValue())))
4677 NewF.canonicalize(*this->L);
4678 (void)InsertFormula(LU, LUIdx, NewF);
4681 for (
size_t N = 0, NE =
F.BaseRegs.size();
N != NE; ++
N) {
4683 if (BaseReg != OrigReg)
4686 if (!NewF.BaseOffset.isCompatibleImmediate(
Imm) ||
4687 !NewF.UnfoldedOffset.isCompatibleImmediate(
Imm) ||
4688 !NewF.BaseOffset.isCompatibleImmediate(NewF.UnfoldedOffset))
4690 NewF.BaseOffset = NewF.BaseOffset.addUnsigned(
Imm);
4692 LU.Kind, LU.AccessTy, NewF)) {
4696 Immediate NewUnfoldedOffset = NewF.UnfoldedOffset.addUnsigned(
Imm);
4700 NewF.UnfoldedOffset = NewUnfoldedOffset;
4702 NewF.BaseRegs[
N] = SE.
getAddExpr(NegImmS, BaseReg);
4707 for (
const SCEV *NewReg : NewF.BaseRegs)
4709 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4711 if ((
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4713 .slt(std::abs(NewF.BaseOffset.getFixedValue())) &&
4714 (
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4717 NewF.BaseOffset.getFixedValue()))
4722 NewF.canonicalize(*this->L);
4723 (void)InsertFormula(LU, LUIdx, NewF);
4734LSRInstance::GenerateAllReuseFormulae() {
4737 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4738 LSRUse &LU =
Uses[LUIdx];
4739 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4740 GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
4741 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4742 GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
4744 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4745 LSRUse &LU =
Uses[LUIdx];
4746 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4747 GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
4748 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4749 GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
4750 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4751 GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
4752 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4753 GenerateScales(LU, LUIdx, LU.Formulae[i]);
4755 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4756 LSRUse &LU =
Uses[LUIdx];
4757 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4758 GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
4761 GenerateCrossUseConstantOffsets();
4764 "After generating reuse formulae:\n";
4765 print_uses(
dbgs()));
4770void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
4771 DenseSet<const SCEV *> VisitedRegs;
4772 SmallPtrSet<const SCEV *, 16> Regs;
4773 SmallPtrSet<const SCEV *, 16> LoserRegs;
4775 bool ChangedFormulae =
false;
4780 using BestFormulaeTy = DenseMap<SmallVector<const SCEV *, 4>,
size_t>;
4782 BestFormulaeTy BestFormulae;
4784 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4785 LSRUse &LU =
Uses[LUIdx];
4790 for (
size_t FIdx = 0, NumForms = LU.Formulae.size();
4791 FIdx != NumForms; ++FIdx) {
4792 Formula &
F = LU.Formulae[FIdx];
4801 Cost CostF(Opts, L, SE,
TTI, AMK);
4803 CostF.RateFormula(
F, Regs, VisitedRegs, LU, HardwareLoopProfitable,
4805 if (CostF.isLoser()) {
4817 for (
const SCEV *
Reg :
F.BaseRegs) {
4818 if (RegUses.isRegUsedByUsesOtherThan(
Reg, LUIdx))
4822 RegUses.isRegUsedByUsesOtherThan(
F.ScaledReg, LUIdx))
4823 Key.push_back(
F.ScaledReg);
4828 std::pair<BestFormulaeTy::const_iterator, bool>
P =
4829 BestFormulae.insert(std::make_pair(
Key, FIdx));
4833 Formula &Best = LU.Formulae[
P.first->second];
4835 Cost CostBest(Opts, L, SE,
TTI, AMK);
4837 CostBest.RateFormula(Best, Regs, VisitedRegs, LU,
4838 HardwareLoopProfitable);
4839 if (CostF.isLess(CostBest))
4843 " in favor of formula ";
4844 Best.print(
dbgs());
dbgs() <<
'\n');
4847 ChangedFormulae =
true;
4849 LU.DeleteFormula(
F);
4857 LU.RecomputeRegs(LUIdx, RegUses);
4860 BestFormulae.clear();
4865 "After filtering out undesirable candidates:\n";
4873size_t LSRInstance::EstimateSearchSpaceComplexity()
const {
4875 for (
const LSRUse &LU :
Uses) {
4876 size_t FSize = LU.Formulae.size();
4877 if (FSize >= Opts.lsr_complexity_limit) {
4878 Power = Opts.lsr_complexity_limit;
4882 if (Power >= Opts.lsr_complexity_limit)
4891void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
4892 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
4895 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by eliminating formulae "
4896 "which use a superset of registers used by other "
4899 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4900 LSRUse &LU =
Uses[LUIdx];
4902 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
4903 Formula &
F = LU.Formulae[i];
4904 if (
F.BaseOffset.isNonZero() &&
F.BaseOffset.isScalable())
4910 I =
F.BaseRegs.begin(),
E =
F.BaseRegs.end();
I !=
E; ++
I) {
4916 Immediate::getFixed(NewF.BaseOffset.getFixedValue() +
4917 (
uint64_t)
C->getValue()->getSExtValue());
4918 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4919 (
I -
F.BaseRegs.begin()));
4920 if (LU.HasFormulaWithSameRegs(NewF)) {
4923 LU.DeleteFormula(
F);
4934 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4935 (
I -
F.BaseRegs.begin()));
4936 if (LU.HasFormulaWithSameRegs(NewF)) {
4939 LU.DeleteFormula(
F);
4950 LU.RecomputeRegs(LUIdx, RegUses);
4959void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
4960 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
4964 dbgs() <<
"The search space is too complex.\n"
4965 "Narrowing the search space by assuming that uses separated "
4966 "by a constant offset will use the same registers.\n");
4970 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4971 LSRUse &LU =
Uses[LUIdx];
4972 for (
const Formula &
F : LU.Formulae) {
4973 if (
F.BaseOffset.isZero() || (
F.Scale != 0 &&
F.Scale != 1))
4975 assert((LU.Kind == LSRUse::Address || LU.Kind == LSRUse::ICmpZero) &&
4976 "Only address and cmp uses expected to have nonzero BaseOffset");
4978 LSRUse *LUThatHas = FindUseWithSimilarFormula(
F, LU);
4982 if (!reconcileNewOffset(*LUThatHas,
F.BaseOffset,
false,
4983 LU.Kind, LU.AccessTy))
4988 LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
4989 LUThatHas->AllFixupsUnconditional &= LU.AllFixupsUnconditional;
4992 for (LSRFixup &
Fixup : LU.Fixups) {
4993 Fixup.Offset +=
F.BaseOffset;
4994 LUThatHas->pushFixup(
Fixup);
4999 Type *FixupType = LUThatHas->Fixups[0].OperandValToReplace->getType();
5000 for (LSRFixup &
Fixup : LUThatHas->Fixups)
5001 assert(
Fixup.OperandValToReplace->getType() == FixupType &&
5002 "Expected all fixups to have the same type");
5007 for (
size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
5008 Formula &
F = LUThatHas->Formulae[i];
5009 if (!
isLegalUse(
TTI, LUThatHas->MinOffset, LUThatHas->MaxOffset,
5010 LUThatHas->Kind, LUThatHas->AccessTy,
F)) {
5012 LUThatHas->DeleteFormula(
F);
5020 LUThatHas->RecomputeRegs(LUThatHas - &
Uses.front(), RegUses);
5023 DeleteUse(LU, LUIdx);
5036void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
5037 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5040 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by re-filtering out "
5041 "undesirable dedicated registers.\n");
5043 FilterOutUndesirableDedicatedRegisters();
5058void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
5059 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5063 dbgs() <<
"The search space is too complex.\n"
5064 "Narrowing the search space by choosing the best Formula "
5065 "from the Formulae with the same Scale and ScaledReg.\n");
5068 using BestFormulaeTy = DenseMap<std::pair<const SCEV *, int64_t>,
size_t>;
5070 BestFormulaeTy BestFormulae;
5072 bool ChangedFormulae =
false;
5074 DenseSet<const SCEV *> VisitedRegs;
5075 SmallPtrSet<const SCEV *, 16> Regs;
5077 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5078 LSRUse &LU =
Uses[LUIdx];
5083 auto IsBetterThan = [&](Formula &FA, Formula &FB) {
5088 size_t FARegNum = 0;
5089 for (
const SCEV *
Reg : FA.BaseRegs) {
5090 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5091 FARegNum += (NumUses - UsedByIndices.
count() + 1);
5093 size_t FBRegNum = 0;
5094 for (
const SCEV *
Reg : FB.BaseRegs) {
5095 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5096 FBRegNum += (NumUses - UsedByIndices.
count() + 1);
5098 if (FARegNum != FBRegNum)
5099 return FARegNum < FBRegNum;
5103 Cost CostFA(Opts, L, SE,
TTI, AMK);
5104 Cost CostFB(Opts, L, SE,
TTI, AMK);
5106 CostFA.RateFormula(FA, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5108 CostFB.RateFormula(FB, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5109 return CostFA.isLess(CostFB);
5113 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5115 Formula &
F = LU.Formulae[FIdx];
5118 auto P = BestFormulae.insert({{
F.ScaledReg,
F.Scale}, FIdx});
5122 Formula &Best = LU.Formulae[
P.first->second];
5123 if (IsBetterThan(
F, Best))
5127 " in favor of formula ";
5128 Best.print(
dbgs());
dbgs() <<
'\n');
5130 ChangedFormulae =
true;
5132 LU.DeleteFormula(
F);
5138 LU.RecomputeRegs(LUIdx, RegUses);
5141 BestFormulae.clear();
5146 "After filtering out undesirable candidates:\n";
5153void LSRInstance::NarrowSearchSpaceByFilterPostInc() {
5156 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5160 "Narrowing the search space by choosing the lowest "
5161 "register Formula for PostInc Uses.\n");
5163 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5164 LSRUse &LU =
Uses[LUIdx];
5166 if (LU.Kind != LSRUse::Address)
5172 size_t MinRegs = std::numeric_limits<size_t>::max();
5173 for (
const Formula &
F : LU.Formulae)
5174 MinRegs = std::min(
F.getNumRegs(), MinRegs);
5177 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5179 Formula &
F = LU.Formulae[FIdx];
5180 if (
F.getNumRegs() > MinRegs) {
5183 LU.DeleteFormula(
F);
5190 LU.RecomputeRegs(LUIdx, RegUses);
5192 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5199void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
5200 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5204 dbgs() <<
"The search space is too complex.\n"
5205 "Narrowing the search space by merging uses with fixups "
5206 "entirely outside the loop with uses inside the loop.\n");
5208 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5209 LSRUse &LU =
Uses[LUIdx];
5212 if (!LU.AllFixupsOutsideLoop || LU.Formulae.empty() ||
5213 LU.Kind == LSRUse::ICmpZero)
5220 LSRUse *LUToMergeWith =
nullptr;
5221 const Formula &ThisF = LU.Formulae[0];
5222 for (LSRUse &OtherLU :
Uses) {
5224 if (OtherLU.AllFixupsOutsideLoop)
5228 if (OtherLU.Kind == LSRUse::ICmpZero)
5231 if (OtherLU.Formulae.empty())
5234 if (
any_of(OtherLU.Formulae, [&](
const Formula &
F) {
5235 return !isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, OtherLU.Kind,
5236 OtherLU.AccessTy, F);
5243 const Formula &OtherF = OtherLU.Formulae[0];
5244 if (ThisF.BaseRegs == OtherF.BaseRegs &&
5245 ThisF.ScaledReg == OtherF.ScaledReg &&
5246 ThisF.BaseGV == OtherF.BaseGV && ThisF.Scale == OtherF.Scale &&
5247 ThisF.UnfoldedOffset == OtherF.UnfoldedOffset &&
5248 ThisF.BaseOffset == OtherF.BaseOffset) {
5249 LUToMergeWith = &OtherLU;
5260 for (LSRFixup &
Fixup : LU.Fixups) {
5261 LUToMergeWith->pushFixup(
Fixup);
5265 DeleteUse(LU, LUIdx);
5315void LSRInstance::NarrowSearchSpaceByDeletingCostlyFormulas() {
5316 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5324 SmallPtrSet<const SCEV *, 4> UniqRegs;
5328 DenseMap <const SCEV *, float> RegNumMap;
5329 for (
const SCEV *
Reg : RegUses) {
5333 for (
const LSRUse &LU :
Uses) {
5334 if (!LU.Regs.count(
Reg))
5336 float P = LU.getNotSelectedProbability(
Reg);
5342 RegNumMap.
insert(std::make_pair(
Reg, PNotSel));
5346 dbgs() <<
"Narrowing the search space by deleting costly formulas\n");
5349 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5350 LSRUse &LU =
Uses[LUIdx];
5352 if (LU.Formulae.size() < 2)
5357 float FMinRegNum = LU.Formulae[0].getNumRegs();
5358 float FMinARegNum = LU.Formulae[0].getNumRegs();
5360 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5361 Formula &
F = LU.Formulae[i];
5364 for (
const SCEV *BaseReg :
F.BaseRegs) {
5365 if (UniqRegs.
count(BaseReg))
5367 FRegNum += RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5370 RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5372 if (
const SCEV *ScaledReg =
F.ScaledReg) {
5373 if (!UniqRegs.
count(ScaledReg)) {
5375 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5378 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5381 if (FMinRegNum > FRegNum ||
5382 (FMinRegNum == FRegNum && FMinARegNum > FARegNum)) {
5383 FMinRegNum = FRegNum;
5384 FMinARegNum = FARegNum;
5389 dbgs() <<
" with min reg num " << FMinRegNum <<
'\n');
5391 std::swap(LU.Formulae[MinIdx], LU.Formulae[0]);
5392 while (LU.Formulae.size() != 1) {
5395 LU.Formulae.pop_back();
5397 LU.RecomputeRegs(LUIdx, RegUses);
5398 assert(LU.Formulae.size() == 1 &&
"Should be exactly 1 min regs formula");
5399 Formula &
F = LU.Formulae[0];
5415 MemAccessTy AccessType) {
5425 return TTI.isLegalAddressingMode(
5426 AccessType.MemTy,
nullptr,
5427 Diff->getSExtValue(),
5428 true, 0, AccessType.AddrSpace) &&
5429 !
TTI.isLegalAddressingMode(
5430 AccessType.MemTy,
nullptr,
5431 -Diff->getSExtValue(),
5432 true, 0, AccessType.AddrSpace);
5438void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
5441 SmallPtrSet<const SCEV *, 4> Taken;
5442 while (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5449 const SCEV *Best =
nullptr;
5450 unsigned BestNum = 0;
5451 for (
const SCEV *
Reg : RegUses) {
5456 BestNum = RegUses.getUsedByIndices(
Reg).count();
5458 unsigned Count = RegUses.getUsedByIndices(
Reg).count();
5459 if (
Count > BestNum) {
5467 if (
Count == BestNum) {
5468 int LUIdx = RegUses.getUsedByIndices(
Reg).find_first();
5469 if (LUIdx >= 0 &&
Uses[LUIdx].Kind == LSRUse::Address &&
5471 Uses[LUIdx].AccessTy)) {
5478 assert(Best &&
"Failed to find best LSRUse candidate");
5480 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by assuming " << *Best
5481 <<
" will yield profitable reuse.\n");
5486 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5487 LSRUse &LU =
Uses[LUIdx];
5488 if (!LU.Regs.count(Best))
continue;
5491 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5492 Formula &
F = LU.Formulae[i];
5493 if (!
F.referencesReg(Best)) {
5495 LU.DeleteFormula(
F);
5499 assert(e != 0 &&
"Use has no formulae left! Is Regs inconsistent?");
5505 LU.RecomputeRegs(LUIdx, RegUses);
5516void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
5517 NarrowSearchSpaceByDetectingSupersets();
5518 NarrowSearchSpaceByCollapsingUnrolledCode();
5519 NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
5520 if (Opts.lsr_filter_same_scaled_reg)
5521 NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
5522 NarrowSearchSpaceByFilterPostInc();
5523 NarrowSearchSpaceByMergingUsesOutsideLoop();
5524 if (Opts.lsr_exp_narrow)
5525 NarrowSearchSpaceByDeletingCostlyFormulas();
5527 NarrowSearchSpaceByPickingWinnerRegs();
5531void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
5533 SmallVectorImpl<const Formula *> &Workspace,
5534 const Cost &CurCost,
5535 const SmallPtrSet<const SCEV *, 16> &CurRegs,
5536 DenseSet<const SCEV *> &VisitedRegs)
const {
5547 const LSRUse &LU =
Uses[Workspace.
size()];
5553 SmallSetVector<const SCEV *, 4> ReqRegs;
5554 for (
const SCEV *S : CurRegs)
5555 if (LU.Regs.count(S))
5558 SmallPtrSet<const SCEV *, 16> NewRegs;
5559 Cost NewCost(Opts, L, SE,
TTI, AMK);
5560 for (
const Formula &
F : LU.Formulae) {
5568 int NumReqRegsToFind = std::min(
F.getNumRegs(), ReqRegs.
size());
5569 for (
const SCEV *
Reg : ReqRegs) {
5570 if ((
F.ScaledReg &&
F.ScaledReg ==
Reg) ||
5573 if (NumReqRegsToFind == 0)
5577 if (NumReqRegsToFind != 0) {
5588 NewCost.RateFormula(
F, NewRegs, VisitedRegs, LU, HardwareLoopProfitable);
5589 if (NewCost.isLess(SolutionCost)) {
5591 if (Workspace.
size() !=
Uses.size()) {
5592 SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
5593 NewRegs, VisitedRegs);
5594 if (
F.getNumRegs() == 1 && Workspace.
size() == 1)
5595 VisitedRegs.
insert(
F.ScaledReg ?
F.ScaledReg :
F.BaseRegs[0]);
5598 dbgs() <<
".\nRegs:\n";
5599 for (
const SCEV *S : NewRegs)
dbgs()
5600 <<
"- " << *S <<
"\n";
5603 SolutionCost = NewCost;
5604 Solution = Workspace;
5613void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution)
const {
5615 Cost SolutionCost(Opts, L, SE,
TTI, AMK);
5616 SolutionCost.Lose();
5617 Cost CurCost(Opts, L, SE,
TTI, AMK);
5618 SmallPtrSet<const SCEV *, 16> CurRegs;
5619 DenseSet<const SCEV *> VisitedRegs;
5623 SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
5624 CurRegs, VisitedRegs);
5625 if (Solution.
empty()) {
5632 "The chosen solution requires ";
5633 SolutionCost.print(
dbgs());
dbgs() <<
":\n";
5634 for (
size_t i = 0, e =
Uses.size(); i != e; ++i) {
5639 Solution[i]->print(
dbgs());
5645 const bool EnableDropUnprofitableSolution =
valueOr(
5648 if (BaselineCost.isLess(SolutionCost)) {
5649 if (!EnableDropUnprofitableSolution)
5651 dbgs() <<
"Baseline is more profitable than chosen solution, "
5652 "add option 'lsr-drop-solution' to drop LSR solution.\n");
5655 "solution, dropping LSR solution.\n";);
5666 const SmallVectorImpl<Instruction *> &Inputs)
5670 bool AllDominate =
true;
5677 for (Instruction *Inst : Inputs) {
5678 if (Inst == Tentative || !DT.
dominates(Inst, Tentative)) {
5679 AllDominate =
false;
5684 if (Tentative->
getParent() == Inst->getParent() &&
5685 (!BetterPos || !DT.
dominates(Inst, BetterPos)))
5695 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
5696 unsigned IPLoopDepth = IPLoop ? IPLoop->
getLoopDepth() : 0;
5700 if (!Rung)
return IP;
5701 Rung = Rung->getIDom();
5702 if (!Rung)
return IP;
5703 IDom = Rung->getBlock();
5706 const Loop *IDomLoop = LI.getLoopFor(IDom);
5707 unsigned IDomDepth = IDomLoop ? IDomLoop->
getLoopDepth() : 0;
5708 if (IDomDepth <= IPLoopDepth &&
5709 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
5726 SmallVector<Instruction *, 4> Inputs;
5729 if (LU.Kind == LSRUse::ICmpZero)
5730 if (Instruction *
I =
5733 if (LF.PostIncLoops.
count(L)) {
5734 if (LF.isUseFullyOutsideLoop(L))
5735 Inputs.
push_back(
L->getLoopLatch()->getTerminator());
5741 for (
const Loop *PIL : LF.PostIncLoops) {
5742 if (PIL == L)
continue;
5747 if (!ExitingBlocks.
empty()) {
5749 for (
unsigned i = 1, e = ExitingBlocks.
size(); i != e; ++i)
5756 "Insertion point must be a normal instruction");
5766 while (IP->isEHPad()) ++IP;
5771 while (
Rewriter.isInsertedInstruction(&*IP) && IP != LowestIP)
5779Value *LSRInstance::Expand(
const LSRUse &LU,
const LSRFixup &LF,
5781 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const {
5782 if (LU.RigidFormula)
5783 return LF.OperandValToReplace;
5787 IP = AdjustInsertPositionForExpand(IP, LF, LU);
5792 Rewriter.setPostInc(LF.PostIncLoops);
5797 Type *Ty =
F.getType();
5810 if (LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy()) {
5819 for (
const SCEV *
Reg :
F.BaseRegs) {
5820 assert(!
Reg->isZero() &&
"Zero allocated in a base register!");
5828 Value *ICmpScaledV =
nullptr;
5830 const SCEV *ScaledS =
F.ScaledReg;
5836 if (LU.Kind == LSRUse::ICmpZero) {
5846 "The only scale supported by ICmpZero uses is -1!");
5847 ICmpScaledV =
Rewriter.expandCodeFor(ScaledS,
nullptr);
5855 if (!
Ops.empty() && LU.Kind == LSRUse::Address &&
5865 Ops.push_back(ScaledS);
5891 assert(
F.BaseOffset.isCompatibleImmediate(LF.Offset) &&
5892 "Expanding mismatched offsets\n");
5894 Immediate
Offset =
F.BaseOffset.addUnsigned(LF.Offset);
5895 if (
Offset.isNonZero()) {
5896 if (LU.Kind == LSRUse::ICmpZero) {
5912 Ops.push_back(
Offset.getUnknownSCEV(SE, IntTy));
5917 Immediate UnfoldedOffset =
F.UnfoldedOffset;
5918 if (UnfoldedOffset.isNonZero()) {
5920 Ops.push_back(UnfoldedOffset.getUnknownSCEV(SE, IntTy));
5934 if (LU.Kind == LSRUse::ICmpZero) {
5938 assert(!
F.BaseGV &&
"ICmp does not support folding a global value and "
5939 "a scale at the same time!");
5940 if (
F.Scale == -1) {
5941 if (ICmpScaledV->
getType() != OpTy) {
5951 assert((
F.Scale == 0 ||
F.Scale == 1) &&
5952 "ICmp does not support folding a global value and "
5953 "a scale at the same time!");
5959 if (
C->getType() != OpTy) {
5963 assert(
C &&
"Cast of ConstantInt should have folded");
5976void LSRInstance::RewriteForPHI(PHINode *PN,
const LSRUse &LU,
5977 const LSRFixup &LF,
const Formula &
F,
5978 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
5979 DenseMap<BasicBlock *, Value *>
Inserted;
5983 bool needUpdateFixups =
false;
5994 Loop *PNLoop = LI.getLoopFor(Parent);
5995 if (!PNLoop || Parent != PNLoop->
getHeader()) {
5999 CriticalEdgeSplittingOptions SplitOptions(&DT, &LI, MSSAU);
6001 SplitOptions.setMergeIdenticalEdges().setKeepOneInputPHIs();
6002 if (ShouldPreserveLCSSA)
6003 SplitOptions = SplitOptions.setPreserveLCSSA();
6007 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
6018 if (
L->contains(BB) && !
L->contains(PN))
6026 needUpdateFixups =
true;
6031 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> Pair =
6044 LF.OperandValToReplace->
getType(),
"tmp",
6051 if (
L->contains(
I) && !
L->contains(BB))
6052 InsertedNonLCSSAInsts.insert(
I);
6055 Pair.first->second = FullV;
6062 if (needUpdateFixups) {
6063 for (LSRUse &LU :
Uses)
6064 for (LSRFixup &
Fixup : LU.Fixups)
6068 if (
Fixup.UserInst == PN) {
6071 bool foundInOriginalPHI =
false;
6073 if (val ==
Fixup.OperandValToReplace) {
6074 foundInOriginalPHI =
true;
6079 if (foundInOriginalPHI)
6090 if (val ==
Fixup.OperandValToReplace)
6091 Fixup.UserInst = NewPN;
6101void LSRInstance::Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
6103 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6107 RewriteForPHI(PN, LU, LF,
F, DeadInsts);
6115 if (FullV->
getType() != OpTy &&
6116 !(LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy())) {
6128 if (LU.Kind == LSRUse::ICmpZero)
6144 const LSRFixup &
Fixup,
const LSRUse &LU,
6148 if (LU.Kind != LSRUse::Address)
6149 return IVIncInsertPos;
6153 Type *Ty =
I->getType();
6156 return IVIncInsertPos;
6163 return IVIncInsertPos;
6170void LSRInstance::ImplementSolution(
6171 const SmallVectorImpl<const Formula *> &Solution) {
6177 for (
const IVChain &Chain : IVChainVec) {
6183 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx)
6184 for (
const LSRFixup &
Fixup :
Uses[LUIdx].Fixups) {
6187 Rewriter.setIVIncInsertPos(L, InsertPos);
6188 Rewrite(
Uses[LUIdx],
Fixup, *Solution[LUIdx], DeadInsts);
6192 auto InsertedInsts = InsertedNonLCSSAInsts.takeVector();
6195 for (
const IVChain &Chain : IVChainVec) {
6196 GenerateIVChain(Chain, DeadInsts);
6200 for (
const WeakVH &
IV :
Rewriter.getInsertedIVs())
6218 for (PHINode &PN :
L->getHeader()->phis()) {
6219 BinaryOperator *BO =
nullptr;
6225 case Instruction::Sub:
6230 case Instruction::Add:
6247 [&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
6256LSRInstance::LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
6257 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
6258 const TargetTransformInfo &
TTI, AssumptionCache &AC,
6259 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
6261 : Opts(Opts), IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI),
TTI(
TTI),
6262 L(
L), MSSAU(MSSAU), AMK(Opts.lsr_preferred_addressing_mode.value_or(
6263 TTI.getPreferredAddressingMode(
L, &SE))),
6264 Rewriter(SE,
"lsr", PreserveLCSSA), ShouldPreserveLCSSA(PreserveLCSSA),
6265 BaselineCost(Opts,
L, SE,
TTI, AMK) {
6267 if (!
L->isLoopSimplifyForm())
6275 unsigned NumUsers = 0;
6279 LLVM_DEBUG(
dbgs() <<
"LSR skipping loop, too many IV Users in " << U
6287 auto FirstNonPHI = PN->
getParent()->getFirstNonPHIIt();
6297 L->getHeader()->printAsOperand(
dbgs(),
false);
6303 HardwareLoopProfitable =
6304 TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo);
6308#if LLVM_ENABLE_ABI_BREAKING_CHECKS
6311 Rewriter.disableCanonicalMode();
6312 Rewriter.enableLSRMode();
6316 OptimizeLoopTermCond();
6319 if (IU.empty())
return;
6322 if (!
L->isInnermost()) {
6335 CollectInterestingTypesAndFactors();
6336 CollectFixupsAndInitialFormulae();
6337 CollectLoopInvariantFixupsAndFormulae();
6343 print_uses(
dbgs()));
6345 BaselineCost.print(
dbgs());
dbgs() <<
"\n");
6349 GenerateAllReuseFormulae();
6351 FilterOutUndesirableDedicatedRegisters();
6352 NarrowSearchSpaceUsingHeuristics();
6362 if (Solution.
empty())
6367 for (
const LSRUse &LU :
Uses) {
6368 for (
const Formula &
F : LU.Formulae)
6370 F) &&
"Illegal formula generated!");
6375 ImplementSolution(Solution);
6378#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
6379void LSRInstance::print_factors_and_types(
raw_ostream &OS)
const {
6380 if (Factors.empty() &&
Types.empty())
return;
6382 OS <<
"LSR has identified the following interesting factors and types: ";
6385 for (int64_t Factor : Factors)
6386 OS <<
LS <<
'*' << Factor;
6388 for (
Type *Ty : Types)
6389 OS <<
LS <<
'(' << *Ty <<
')';
6393void LSRInstance::print_fixups(raw_ostream &OS)
const {
6394 OS <<
"LSR is examining the following fixup sites:\n";
6395 for (
const LSRUse &LU :
Uses)
6396 for (
const LSRFixup &LF : LU.Fixups) {
6403void LSRInstance::print_uses(raw_ostream &OS)
const {
6404 OS <<
"LSR is examining the following uses:\n";
6405 for (
const LSRUse &LU :
Uses) {
6409 for (
const Formula &
F : LU.Formulae) {
6417void LSRInstance::print(raw_ostream &OS)
const {
6418 print_factors_and_types(OS);
6430class LoopStrengthReduce :
public LoopPass {
6434 LoopStrengthReduce();
6437 bool runOnLoop(
Loop *L, LPPassManager &LPM)
override;
6438 void getAnalysisUsage(AnalysisUsage &AU)
const override;
6443LoopStrengthReduce::LoopStrengthReduce() : LoopPass(
ID) {
6447void LoopStrengthReduce::getAnalysisUsage(
AnalysisUsage &AU)
const {
6474ToDwarfOpIter(SmallVectorImpl<uint64_t> &Expr) {
6475 llvm::DIExpression::expr_op_iterator Begin =
6476 llvm::DIExpression::expr_op_iterator(Expr.
begin());
6477 llvm::DIExpression::expr_op_iterator End =
6478 llvm::DIExpression::expr_op_iterator(Expr.
end());
6479 return {Begin, End};
6482struct SCEVDbgValueBuilder {
6483 SCEVDbgValueBuilder() =
default;
6484 SCEVDbgValueBuilder(
const SCEVDbgValueBuilder &
Base) { clone(
Base); }
6486 void clone(
const SCEVDbgValueBuilder &
Base) {
6487 LocationOps =
Base.LocationOps;
6492 LocationOps.
clear();
6499 SmallVector<Value *, 2> LocationOps;
6509 unsigned ArgIndex = 0;
6510 if (It != LocationOps.
end()) {
6511 ArgIndex = std::distance(LocationOps.
begin(), It);
6513 ArgIndex = LocationOps.
size();
6519 void pushValue(
const SCEVUnknown *U) {
6524 bool pushConst(
const SCEVConstant *
C) {
6525 if (
C->getAPInt().getSignificantBits() > 64)
6527 Expr.
push_back(llvm::dwarf::DW_OP_consts);
6528 Expr.
push_back(
C->getAPInt().getSExtValue());
6535 return ToDwarfOpIter(Expr);
6540 bool pushArithmeticExpr(
const llvm::SCEVCommutativeExpr *CommExpr,
6543 "Expected arithmetic SCEV type");
6545 unsigned EmitOperator = 0;
6546 for (
const auto &
Op : CommExpr->
operands()) {
6549 if (EmitOperator >= 1)
6550 pushOperator(DwarfOp);
6557 bool pushCast(
const llvm::SCEVCastExpr *
C,
bool IsSigned) {
6558 const llvm::SCEV *Inner =
C->getOperand(0);
6559 const llvm::Type *
Type =
C->getType();
6561 bool Success = pushSCEV(Inner);
6563 IsSigned ? llvm::dwarf::DW_ATE_signed
6564 : llvm::dwarf::DW_ATE_unsigned};
6565 for (
const auto &
Op : CastOps)
6571 bool pushSCEV(
const llvm::SCEV *S) {
6574 Success &= pushConst(StartInt);
6579 pushLocation(
U->getValue());
6582 Success &= pushArithmeticExpr(MulRec, llvm::dwarf::DW_OP_mul);
6585 Success &= pushSCEV(UDiv->getLHS());
6586 Success &= pushSCEV(UDiv->getRHS());
6587 pushOperator(llvm::dwarf::DW_OP_div);
6593 "Unexpected cast type in SCEV.");
6597 Success &= pushArithmeticExpr(AddExpr, llvm::dwarf::DW_OP_plus);
6612 bool isIdentityFunction(
uint64_t Op,
const SCEV *S) {
6614 if (
C->getAPInt().getSignificantBits() > 64)
6616 int64_t
I =
C->getAPInt().getSExtValue();
6618 case llvm::dwarf::DW_OP_plus:
6619 case llvm::dwarf::DW_OP_minus:
6621 case llvm::dwarf::DW_OP_mul:
6622 case llvm::dwarf::DW_OP_div:
6635 bool SCEVToValueExpr(
const llvm::SCEVAddRecExpr &SAR, ScalarEvolution &SE) {
6641 if (!isIdentityFunction(llvm::dwarf::DW_OP_mul, Stride)) {
6642 if (!pushSCEV(Stride))
6644 pushOperator(llvm::dwarf::DW_OP_mul);
6646 if (!isIdentityFunction(llvm::dwarf::DW_OP_plus, Start)) {
6647 if (!pushSCEV(Start))
6649 pushOperator(llvm::dwarf::DW_OP_plus);
6655 void createOffsetExpr(int64_t
Offset,
Value *OffsetValue) {
6656 pushLocation(OffsetValue);
6659 dbgs() <<
"scev-salvage: Generated IV offset expression. Offset: "
6660 << std::to_string(
Offset) <<
"\n");
6666 bool createIterCountExpr(
const SCEV *S,
6667 const SCEVDbgValueBuilder &IterationCount,
6668 ScalarEvolution &SE) {
6677 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Location to salvage SCEV: " << *S
6681 if (!Rec->isAffine())
6689 clone(IterationCount);
6690 if (!SCEVToValueExpr(*Rec, SE))
6701 bool SCEVToIterCountExpr(
const llvm::SCEVAddRecExpr &SAR,
6702 ScalarEvolution &SE) {
6708 if (!isIdentityFunction(llvm::dwarf::DW_OP_minus, Start)) {
6709 if (!pushSCEV(Start))
6711 pushOperator(llvm::dwarf::DW_OP_minus);
6713 if (!isIdentityFunction(llvm::dwarf::DW_OP_div, Stride)) {
6714 if (!pushSCEV(Stride))
6716 pushOperator(llvm::dwarf::DW_OP_div);
6724 void appendToVectors(SmallVectorImpl<uint64_t> &DestExpr,
6725 SmallVectorImpl<Value *> &DestLocations) {
6727 "Expected the locations vector to contain the IV");
6732 "Expected the location ops to contain the IV.");
6736 for (
const auto &
Op : LocationOps) {
6737 auto It =
find(DestLocations,
Op);
6738 if (It != DestLocations.
end()) {
6740 DestIndexMap.
push_back(std::distance(DestLocations.
begin(), It));
6748 for (
const auto &
Op : expr_ops()) {
6751 Op.appendToVector(DestExpr);
6758 uint64_t NewIndex = DestIndexMap[Arg.getIndex()];
6766struct DVIRecoveryRec {
6767 DVIRecoveryRec(DbgVariableRecord *DVR)
6768 : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(
false) {}
6770 DbgVariableRecord *DbgRef;
6772 bool HadLocationArgList;
6778 for (
auto &RE : RecoveryExprs)
6780 RecoveryExprs.clear();
6783 ~DVIRecoveryRec() { clear(); }
6791 auto expr_ops = ToDwarfOpIter(Expr);
6793 for (
auto Op : expr_ops)
6802template <
typename T>
6806 "contain any DW_OP_llvm_arg operands.");
6812template <
typename T>
6817 "Expected expression that references DIArglist locations using "
6818 "DW_OP_llvm_arg operands.");
6820 for (
Value *V : Locations)
6837 if (NumLLVMArgs == 0) {
6844 "Lone LLVM_arg in a DIExpression should refer to location-op 0.");
6874 LLVM_DEBUG(
dbgs() <<
"scev-salvage: restore dbg.value to pre-LSR state\n"
6875 <<
"scev-salvage: post-LSR: " << *DbgVal <<
'\n');
6876 assert(DVIRec.Expr &&
"Expected an expression");
6881 if (!DVIRec.HadLocationArgList) {
6882 assert(DVIRec.LocationOps.size() == 1 &&
6883 "Unexpected number of location ops.");
6887 Value *CachedValue =
6892 for (
WeakVH VH : DVIRec.LocationOps) {
6900 LLVM_DEBUG(
dbgs() <<
"scev-salvage: pre-LSR: " << *DbgVal <<
'\n');
6905 const SCEV *SCEVInductionVar,
6906 SCEVDbgValueBuilder IterCountExpr) {
6920 LocationOpIndexMap.
assign(DVIRec.LocationOps.size(), -1);
6922 NewLocationOps.
push_back(LSRInductionVar);
6924 for (
unsigned i = 0; i < DVIRec.LocationOps.size(); i++) {
6925 WeakVH VH = DVIRec.LocationOps[i];
6931 LocationOpIndexMap[i] = NewLocationOps.
size() - 1;
6933 <<
" now at index " << LocationOpIndexMap[i] <<
"\n");
6941 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV for location at index: " << i
6942 <<
" refers to a location that is now undef or erased. "
6943 "Salvage abandoned.\n");
6947 LLVM_DEBUG(
dbgs() <<
"scev-salvage: salvaging location at index " << i
6948 <<
" with SCEV: " << *DVIRec.SCEVs[i] <<
"\n");
6950 DVIRec.RecoveryExprs[i] = std::make_unique<SCEVDbgValueBuilder>();
6951 SCEVDbgValueBuilder *SalvageExpr = DVIRec.RecoveryExprs[i].get();
6955 if (std::optional<APInt>
Offset =
6957 if (
Offset->getSignificantBits() <= 64)
6958 SalvageExpr->createOffsetExpr(
Offset->getSExtValue(), LSRInductionVar);
6961 }
else if (!SalvageExpr->createIterCountExpr(DVIRec.SCEVs[i], IterCountExpr,
6970 assert(DVIRec.RecoveryExprs.size() == 1 &&
6971 "Expected only a single recovery expression for an empty "
6973 assert(DVIRec.RecoveryExprs[0] &&
6974 "Expected a SCEVDbgSalvageBuilder for location 0");
6975 SCEVDbgValueBuilder *
B = DVIRec.RecoveryExprs[0].get();
6976 B->appendToVectors(
NewExpr, NewLocationOps);
6978 for (
const auto &
Op : DVIRec.Expr->
expr_ops()) {
6986 uint64_t LocationArgIndex = Arg.getIndex();
6987 SCEVDbgValueBuilder *DbgBuilder =
6988 DVIRec.RecoveryExprs[LocationArgIndex].get();
6994 assert(LocationOpIndexMap[LocationArgIndex] != -1 &&
6995 "Expected a positive index for the location-op position.");
6996 NewExpr.push_back(LocationOpIndexMap[LocationArgIndex]);
7000 DbgBuilder->appendToVectors(
NewExpr, NewLocationOps);
7004 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Updated DVI: " << *DVIRec.DbgRef <<
"\n");
7012 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &DVIToUpdate) {
7013 if (DVIToUpdate.empty())
7017 assert(SCEVInductionVar &&
7018 "Anticipated a SCEV for the post-LSR induction variable");
7022 if (!IVAddRec->isAffine())
7030 SCEVDbgValueBuilder IterCountExpr;
7031 IterCountExpr.pushLocation(LSRInductionVar);
7032 if (!IterCountExpr.SCEVToIterCountExpr(*IVAddRec, SE))
7035 LLVM_DEBUG(
dbgs() <<
"scev-salvage: IV SCEV: " << *SCEVInductionVar
7038 for (
auto &DVIRec : DVIToUpdate) {
7039 SalvageDVI(L, SE, LSRInductionVar, *DVIRec, SCEVInductionVar,
7050 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &SalvageableDVISCEVs) {
7051 for (
const auto &
B : L->getBlocks()) {
7052 for (
auto &
I : *
B) {
7054 if (!DbgVal.isDbgValue() && !DbgVal.isDbgAssign())
7059 if (DbgVal.isKillLocation())
7064 const auto &HasTranslatableLocationOps =
7066 for (
const auto LocOp : DbgValToTranslate.location_ops()) {
7080 if (!HasTranslatableLocationOps(DbgVal))
7083 std::unique_ptr<DVIRecoveryRec> NewRec =
7084 std::make_unique<DVIRecoveryRec>(&DbgVal);
7088 NewRec->RecoveryExprs.resize(DbgVal.getNumVariableLocationOps());
7089 for (
const auto LocOp : DbgVal.location_ops()) {
7090 NewRec->SCEVs.push_back(SE.
getSCEV(LocOp));
7091 NewRec->LocationOps.push_back(LocOp);
7092 NewRec->HadLocationArgList = DbgVal.hasArgList();
7094 SalvageableDVISCEVs.push_back(std::move(NewRec));
7104 const LSRInstance &LSR) {
7106 auto IsSuitableIV = [&](
PHINode *
P) {
7117 for (
const WeakVH &
IV : LSR.getScalarEvolutionIVs()) {
7124 if (IsSuitableIV(
P))
7128 for (
PHINode &
P : L.getHeader()->phis()) {
7129 if (IsSuitableIV(&
P))
7140 const ScalarOptions &Opts = ScalarOptions::Global;
7148 std::unique_ptr<MemorySSAUpdater> MSSAU;
7150 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
7153 const LSRInstance &Reducer = LSRInstance(Opts, L, IU, SE, DT, LI,
TTI, AC,
7154 TLI, MSSAU.get(), PreserveLCSSA);
7155 Changed |= Reducer.getChanged();
7159 if (Opts.enable_lsr_phielim && L->isLoopSimplifyForm()) {
7162#if LLVM_ENABLE_ABI_BREAKING_CHECKS
7165 unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &
TTI);
7179 if (L->isRecursivelyLCSSAForm(DT, LI) && L->getExitBlock()) {
7193 if (SalvageableDVIRecords.
empty())
7199 for (
const auto &L : LI) {
7203 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV salvaging not possible. An IV "
7204 "could not be identified.\n");
7208 for (
auto &Rec : SalvageableDVIRecords)
7210 SalvageableDVIRecords.
clear();
7214bool LoopStrengthReduce::runOnLoop(
Loop *L, LPPassManager & ) {
7218 auto &IU = getAnalysis<IVUsersWrapperPass>().getIU();
7219 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
7220 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7221 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
7222 const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
7223 *
L->getHeader()->getParent());
7224 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
7225 *
L->getHeader()->getParent());
7226 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
7227 *
L->getHeader()->getParent());
7228 auto *MSSAAnalysis = getAnalysisIfAvailable<MemorySSAWrapperPass>();
7231 MSSA = &MSSAAnalysis->getMSSA();
7250char LoopStrengthReduce::ID = 0;
7253 "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!")
AArch64 Predicate As Counter Loop Rewrites
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 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 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 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 > 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 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 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 Immediate extractImmediate(const ScalarOptions &Opts, SCEVUse &S, ScalarEvolution &SE, bool PreferScalable=false)
If S involves the addition of a constant integer value, return that integer value,...
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 bool isAlwaysFoldable(const ScalarOptions &Opts, const TargetTransformInfo &TTI, LSRUse::KindType Kind, MemAccessTy AccessTy, GlobalValue *BaseGV, Immediate BaseOffset, bool HasBaseReg)
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 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 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 Immediate extractImmediateOperand(const ScalarOptions &Opts, MutableArrayRef< SCEVUse > Ops, ScalarEvolution &SE, bool PreferScalable)
Extracts an immediate operand from Ops and replaces the operand with zero.
static void updateDVIWithLocations(T &DbgVal, SmallVectorImpl< Value * > &Locations, SmallVectorImpl< uint64_t > &Ops)
Overwrite DVI with locations placed into a DIArglist.
static bool canFoldIVIncExpr(const ScalarOptions &Opts, const SCEV *IncExpr, Instruction *UserInst, Value *Operand, const TargetTransformInfo &TTI)
Return true if the IVInc can be folded into an addressing mode.
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 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)
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)
virt reg 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 > insert(const std::pair< KeyT, ValueT > &KV)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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.
iterator_range< user_iterator > users()
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.
LLVM_ABI ArrayRef< SCEVUse > operands() const
Return operands of this SCEV expression.
Type * getType() const
Return the LLVM type of this SCEV expression.
static constexpr auto FlagNone
SCEVTypes getSCEVType() const
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 const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
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 * getNoopOrSignExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
LLVM_ABI SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEVFlagsPair Flags)
Get an add recurrence expression for the specified loop.
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 SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
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(SCEVUse Op, Type *Ty)
getAnyExtendExpr - Return a SCEV for the given operand extended with unspecified bits out to the give...
LLVM_ABI const SCEV * getSignExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool containsUndefs(const SCEV *S) const
Return true if the SCEV expression contains an undef value.
LLVM_ABI const SCEV * getVScale(Type *Ty)
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
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 * 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.
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 bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
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.
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.
@ 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.
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...
@ Store
The extracted value is stored (ExtractElement only).
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
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.
constexpr bool valueOr(BoolOrDefault X, bool Default)
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.
SCEVPtrT getPointer() const