132#define DEBUG_TYPE "loop-reduce"
148 return Opts.stress_ivchain;
158 static const unsigned UnknownAddressSpace =
159 std::numeric_limits<unsigned>::max();
161 Type *MemTy =
nullptr;
162 unsigned AddrSpace = UnknownAddressSpace;
164 MemAccessTy() =
default;
165 MemAccessTy(
Type *Ty,
unsigned AS) : MemTy(Ty), AddrSpace(AS) {}
168 return MemTy ==
Other.MemTy && AddrSpace ==
Other.AddrSpace;
173 static MemAccessTy getUnknown(LLVMContext &Ctx,
174 unsigned AS = UnknownAddressSpace) {
175 return MemAccessTy(Type::getVoidTy(Ctx), AS);
186 SmallBitVector UsedByIndices;
188 void print(raw_ostream &OS)
const;
195 constexpr Immediate(ScalarTy MinVal,
bool Scalable)
196 : FixedOrScalableQuantity(MinVal, Scalable) {}
198 constexpr Immediate(
const FixedOrScalableQuantity<Immediate, int64_t> &V)
199 : FixedOrScalableQuantity(
V) {}
202 constexpr Immediate() =
delete;
204 static constexpr Immediate getFixed(ScalarTy MinVal) {
205 return {MinVal,
false};
207 static constexpr Immediate getScalable(ScalarTy MinVal) {
208 return {MinVal,
true};
210 static constexpr Immediate
get(ScalarTy MinVal,
bool Scalable) {
211 return {MinVal, Scalable};
213 static constexpr Immediate getZero() {
return {0,
false}; }
214 static constexpr Immediate getFixedMin() {
215 return {std::numeric_limits<int64_t>::min(),
false};
217 static constexpr Immediate getFixedMax() {
218 return {std::numeric_limits<int64_t>::max(),
false};
220 static constexpr Immediate getScalableMin() {
221 return {std::numeric_limits<int64_t>::min(),
true};
223 static constexpr Immediate getScalableMax() {
224 return {std::numeric_limits<int64_t>::max(),
true};
227 constexpr bool isLessThanZero()
const {
return Quantity < 0; }
229 constexpr bool isGreaterThanZero()
const {
return Quantity > 0; }
231 constexpr bool isCompatibleImmediate(
const Immediate &
Imm)
const {
232 return isZero() ||
Imm.isZero() ||
Imm.Scalable == Scalable;
235 constexpr bool isMin()
const {
236 return Quantity == std::numeric_limits<ScalarTy>::min();
239 constexpr bool isMax()
const {
240 return Quantity == std::numeric_limits<ScalarTy>::max();
244 constexpr Immediate addUnsigned(
const Immediate &
RHS)
const {
245 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
247 return {
Value, Scalable ||
RHS.isScalable()};
250 constexpr Immediate subUnsigned(
const Immediate &
RHS)
const {
251 assert(isCompatibleImmediate(
RHS) &&
"Incompatible Immediates");
253 return {
Value, Scalable ||
RHS.isScalable()};
257 constexpr Immediate mulUnsigned(
const ScalarTy
RHS)
const {
259 return {
Value, Scalable};
263 const SCEV *getSCEV(ScalarEvolution &SE,
Type *Ty)
const {
270 const SCEV *getNegativeSCEV(ScalarEvolution &SE,
Type *Ty)
const {
277 const SCEV *getUnknownSCEV(ScalarEvolution &SE,
Type *Ty)
const {
292struct KeyOrderTargetImmediate {
293 bool operator()(
const Immediate &
LHS,
const Immediate &
RHS)
const {
294 if (
LHS.isScalable() && !
RHS.isScalable())
296 if (!
LHS.isScalable() &&
RHS.isScalable())
298 return LHS.getKnownMinValue() <
RHS.getKnownMinValue();
305struct KeyOrderSizeTAndImmediate {
306 bool operator()(
const std::pair<size_t, Immediate> &
LHS,
307 const std::pair<size_t, Immediate> &
RHS)
const {
308 size_t LSize =
LHS.first;
309 size_t RSize =
RHS.first;
311 return LSize < RSize;
312 return KeyOrderTargetImmediate()(
LHS.second,
RHS.second);
317#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
319 OS <<
"[NumUses=" << UsedByIndices.
count() <<
']';
331 using RegUsesTy = DenseMap<const SCEV *, RegSortData>;
333 RegUsesTy RegUsesMap;
337 void countRegister(
const SCEV *
Reg,
size_t LUIdx);
338 void dropRegister(
const SCEV *
Reg,
size_t LUIdx);
339 void swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx);
341 bool isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const;
343 const SmallBitVector &getUsedByIndices(
const SCEV *
Reg)
const;
359RegUseTracker::countRegister(
const SCEV *
Reg,
size_t LUIdx) {
360 std::pair<RegUsesTy::iterator, bool> Pair = RegUsesMap.try_emplace(
Reg);
361 RegSortData &RSD = Pair.first->second;
364 RSD.UsedByIndices.
resize(std::max(RSD.UsedByIndices.
size(), LUIdx + 1));
365 RSD.UsedByIndices.
set(LUIdx);
369RegUseTracker::dropRegister(
const SCEV *
Reg,
size_t LUIdx) {
370 RegUsesTy::iterator It = RegUsesMap.find(
Reg);
371 assert(It != RegUsesMap.end());
372 RegSortData &RSD = It->second;
374 RSD.UsedByIndices.
reset(LUIdx);
378RegUseTracker::swapAndDropUse(
size_t LUIdx,
size_t LastLUIdx) {
379 assert(LUIdx <= LastLUIdx);
383 for (
auto &Pair : RegUsesMap) {
384 SmallBitVector &UsedByIndices = Pair.second.UsedByIndices;
385 if (LUIdx < UsedByIndices.
size())
386 UsedByIndices[LUIdx] =
387 LastLUIdx < UsedByIndices.
size() ? UsedByIndices[LastLUIdx] :
false;
388 UsedByIndices.
resize(std::min(UsedByIndices.
size(), LastLUIdx));
393RegUseTracker::isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const {
394 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
395 if (
I == RegUsesMap.end())
397 const SmallBitVector &UsedByIndices =
I->second.UsedByIndices;
399 if (i == -1)
return false;
400 if ((
size_t)i != LUIdx)
return true;
404const SmallBitVector &RegUseTracker::getUsedByIndices(
const SCEV *
Reg)
const {
405 RegUsesTy::const_iterator
I = RegUsesMap.find(
Reg);
406 assert(
I != RegUsesMap.end() &&
"Unknown register!");
407 return I->second.UsedByIndices;
410void RegUseTracker::clear() {
421 GlobalValue *BaseGV =
nullptr;
424 Immediate BaseOffset = Immediate::getZero();
427 bool HasBaseReg =
false;
450 const SCEV *ScaledReg =
nullptr;
455 Immediate UnfoldedOffset = Immediate::getZero();
459 void initialMatch(
const SCEV *S,
Loop *L, ScalarEvolution &SE);
463 void canonicalize(
const Loop &L);
467 bool hasZeroEnd()
const;
469 bool countsDownToZero()
const;
471 size_t getNumRegs()
const;
474 void deleteBaseReg(
const SCEV *&S);
476 bool referencesReg(
const SCEV *S)
const;
477 bool hasRegsUsedByUsesOtherThan(
size_t LUIdx,
478 const RegUseTracker &RegUses)
const;
480 void print(raw_ostream &OS)
const;
498 for (
const SCEV *S :
Add->operands())
504 const SCEV *Start, *Step;
519 if (
Mul->getOperand(0)->isAllOnesValue()) {
528 for (
const SCEV *S : MyGood)
530 for (
const SCEV *S : MyBad)
542void Formula::initialMatch(
const SCEV *S,
Loop *L, ScalarEvolution &SE) {
549 BaseRegs.push_back(Sum);
555 BaseRegs.push_back(Sum);
570bool Formula::isCanonical(
const Loop &L)
const {
571 assert((Scale == 0 || ScaledReg) &&
572 "ScaledReg must be non-null if Scale is non-zero");
575 return BaseRegs.size() <= 1;
580 if (Scale == 1 && BaseRegs.empty())
589 return none_of(BaseRegs, [&L](
const SCEV *S) {
600void Formula::canonicalize(
const Loop &L) {
604 if (BaseRegs.empty()) {
606 assert(ScaledReg &&
"Expected 1*reg => reg");
607 assert(Scale == 1 &&
"Expected 1*reg => reg");
608 BaseRegs.push_back(ScaledReg);
616 ScaledReg = BaseRegs.pop_back_val();
624 auto I =
find_if(BaseRegs, [&L](
const SCEV *S) {
627 if (
I != BaseRegs.end())
637bool Formula::unscale() {
641 BaseRegs.push_back(ScaledReg);
646bool Formula::hasZeroEnd()
const {
647 if (UnfoldedOffset || BaseOffset)
649 if (BaseRegs.size() != 1 || ScaledReg)
654bool Formula::countsDownToZero()
const {
657 assert(BaseRegs.size() == 1 &&
"hasZeroEnd should mean one BaseReg");
658 const APInt *StepInt;
666size_t Formula::getNumRegs()
const {
667 return !!ScaledReg + BaseRegs.size();
672Type *Formula::getType()
const {
673 return !BaseRegs.empty() ? BaseRegs.front()->getType() :
674 ScaledReg ? ScaledReg->
getType() :
680void Formula::deleteBaseReg(
const SCEV *&S) {
681 if (&S != &BaseRegs.back())
687bool Formula::referencesReg(
const SCEV *S)
const {
693bool Formula::hasRegsUsedByUsesOtherThan(
size_t LUIdx,
694 const RegUseTracker &RegUses)
const {
696 if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
698 for (
const SCEV *BaseReg : BaseRegs)
699 if (RegUses.isRegUsedByUsesOtherThan(BaseReg, LUIdx))
704#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
705void Formula::print(raw_ostream &OS)
const {
706 ListSeparator
Plus(
" + ");
711 if (BaseOffset.isNonZero())
712 OS <<
Plus << BaseOffset;
714 for (
const SCEV *BaseReg : BaseRegs)
717 if (HasBaseReg && BaseRegs.empty())
718 OS <<
Plus <<
"**error: HasBaseReg**";
719 else if (!HasBaseReg && !BaseRegs.empty())
720 OS <<
Plus <<
"**error: !HasBaseReg**";
723 OS <<
Plus << Scale <<
"*reg(";
730 if (UnfoldedOffset.isNonZero())
731 OS <<
Plus <<
"imm(" << UnfoldedOffset <<
')';
771 bool IgnoreSignificantBits =
false) {
782 if (
RA.isAllOnes()) {
783 if (
LHS->getType()->isPointerTy())
796 const APInt &LA =
C->getAPInt();
805 if ((IgnoreSignificantBits ||
isAddRecSExtable(AR, SE)) && AR->isAffine()) {
807 IgnoreSignificantBits);
808 if (!Step)
return nullptr;
810 IgnoreSignificantBits);
811 if (!Start)
return nullptr;
824 for (
const SCEV *S :
Add->operands()) {
826 if (!
Op)
return nullptr;
854 for (
const SCEV *S :
Mul->operands()) {
857 IgnoreSignificantBits)) {
878 bool PreferScalable) {
881 Immediate Result = Immediate::getZero();
890 C->getSignificantBits() <= 64) {
892 Result = Immediate::getFixed(
C->getSExtValue());
897 if (Opts.lsr_enable_vscale_immediates &&
898 (Result.isZero() || PreferScalable)) {
905 Result = Immediate::getScalable(
C->getSExtValue());
911 if (Result.isNonZero()) {
923 bool PreferScalable =
false) {
930 if (Result.isNonZero())
937 if (Result.isNonZero())
978 if (
SI->getPointerOperand() == OperandVal)
983 switch (
II->getIntrinsicID()) {
984 case Intrinsic::memset:
985 case Intrinsic::prefetch:
986 case Intrinsic::masked_load:
987 if (
II->getArgOperand(0) == OperandVal)
990 case Intrinsic::masked_store:
991 if (
II->getArgOperand(1) == OperandVal)
994 case Intrinsic::memmove:
995 case Intrinsic::memcpy:
996 if (
II->getArgOperand(0) == OperandVal ||
997 II->getArgOperand(1) == OperandVal)
1002 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo)) {
1003 if (IntrInfo.
PtrVal == OperandVal)
1009 if (RMW->getPointerOperand() == OperandVal)
1012 if (CmpX->getPointerOperand() == OperandVal)
1021 MemAccessTy AccessTy = MemAccessTy::getUnknown(Inst->
getContext());
1025 AccessTy.MemTy = Ty;
1029 AccessTy.AddrSpace =
SI->getPointerAddressSpace();
1031 AccessTy.AddrSpace = LI->getPointerAddressSpace();
1033 AccessTy.AddrSpace = RMW->getPointerAddressSpace();
1035 AccessTy.AddrSpace = CmpX->getPointerAddressSpace();
1037 switch (
II->getIntrinsicID()) {
1038 case Intrinsic::prefetch:
1039 case Intrinsic::memset:
1040 AccessTy.AddrSpace =
II->getArgOperand(0)->getType()->getPointerAddressSpace();
1041 AccessTy.MemTy = OperandVal->
getType();
1043 case Intrinsic::memmove:
1044 case Intrinsic::memcpy:
1046 AccessTy.MemTy = OperandVal->
getType();
1048 case Intrinsic::masked_load:
1049 AccessTy.AddrSpace =
1050 II->getArgOperand(0)->getType()->getPointerAddressSpace();
1052 case Intrinsic::masked_store:
1053 AccessTy.AddrSpace =
1054 II->getArgOperand(1)->getType()->getPointerAddressSpace();
1058 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo) && IntrInfo.
PtrVal) {
1114 if (!Processed.
insert(S).second)
1118 for (
const SCEV *S :
Add->operands()) {
1125 const SCEV *Op0, *Op1;
1134 Value *UVal = U->getValue();
1138 if (UI && UI->
getOpcode() == Instruction::Mul &&
1171 const LSRUse &LU,
const Formula &
F);
1175 const LSRUse &LU,
const Formula &
F,
1182 const ScalarOptions *Opts =
nullptr;
1183 const Loop *
L =
nullptr;
1184 ScalarEvolution *SE =
nullptr;
1185 const TargetTransformInfo *
TTI =
nullptr;
1186 TargetTransformInfo::LSRCost
C;
1191 Cost(
const ScalarOptions &Opts,
const Loop *L, ScalarEvolution &SE,
1193 : Opts(&Opts),
L(
L), SE(&SE),
TTI(&
TTI), AMK(AMK) {
1211 return ((
C.Insns |
C.NumRegs |
C.AddRecCost |
C.NumIVMuls |
C.NumBaseAdds
1212 |
C.ImmCost |
C.SetupCost |
C.ScaleCost) != ~0u)
1213 || ((
C.Insns &
C.NumRegs &
C.AddRecCost &
C.NumIVMuls &
C.NumBaseAdds
1214 &
C.ImmCost &
C.SetupCost &
C.ScaleCost) == ~0
u);
1220 return C.NumRegs == ~0
u;
1223 void RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1224 const DenseSet<const SCEV *> &VisitedRegs,
const LSRUse &LU,
1225 bool HardwareLoopProfitable,
1226 SmallPtrSetImpl<const SCEV *> *LoserRegs =
nullptr);
1228 void print(raw_ostream &OS)
const;
1232 void RateRegister(
const Formula &
F,
const SCEV *
Reg,
1233 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1234 bool HardwareLoopProfitable);
1235 void RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1236 SmallPtrSetImpl<const SCEV *> &Regs,
1237 const LSRUse &LU,
bool HardwareLoopProfitable,
1238 SmallPtrSetImpl<const SCEV *> *LoserRegs);
1249 Value *OperandValToReplace =
nullptr;
1259 Immediate
Offset = Immediate::getZero();
1261 LSRFixup() =
default;
1263 bool isUseFullyOutsideLoop(
const Loop *L)
const;
1265 void print(raw_ostream &OS)
const;
1275 DenseSet<SmallVector<const SCEV *, 4>> Uniquifier;
1288 using SCEVUseKindPair = PointerIntPair<const SCEV *, 2, KindType>;
1291 MemAccessTy AccessTy;
1297 Immediate MinOffset = Immediate::getFixedMax();
1298 Immediate MaxOffset = Immediate::getFixedMin();
1302 bool AllFixupsOutsideLoop =
true;
1307 bool AllFixupsUnconditional =
true;
1314 bool RigidFormula =
false;
1322 SmallPtrSet<const SCEV *, 4> Regs;
1324 LSRUse(KindType K, MemAccessTy AT) :
Kind(
K), AccessTy(AT) {}
1326 LSRFixup &getNewFixup() {
1327 Fixups.push_back(LSRFixup());
1331 void pushFixup(LSRFixup &f) {
1333 if (Immediate::isKnownGT(
f.Offset, MaxOffset))
1334 MaxOffset =
f.Offset;
1335 if (Immediate::isKnownLT(
f.Offset, MinOffset))
1336 MinOffset =
f.Offset;
1339 bool HasFormulaWithSameRegs(
const Formula &
F)
const;
1340 float getNotSelectedProbability(
const SCEV *
Reg)
const;
1341 bool InsertFormula(
const Formula &
F,
const Loop &L);
1342 void DeleteFormula(Formula &
F);
1343 void RecomputeRegs(
size_t LUIdx, RegUseTracker &Reguses);
1345 void print(raw_ostream &OS)
const;
1352 LSRUse::KindType Kind, MemAccessTy AccessTy,
1353 GlobalValue *BaseGV, Immediate BaseOffset,
1354 bool HasBaseReg, int64_t Scale,
1355 Instruction *
Fixup =
nullptr);
1362 if (
TTI.getIntImmCost(
C->getAPInt(),
C->getType(),
1376 [&](
unsigned i,
const SCEV *
Reg) {
1377 return i + getSetupCost(Reg, Depth - 1, TTI);
1386void Cost::RateRegister(
const Formula &
F,
const SCEV *
Reg,
1387 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1388 bool HardwareLoopProfitable) {
1393 if (AR->getLoop() != L) {
1400 if (!AR->getLoop()->contains(L)) {
1410 unsigned LoopCost = 1;
1419 F.BaseOffset.isFixed() &&
1420 *Step ==
F.BaseOffset.getFixedValue();
1425 if ((CanPreIndex || CanPostIndex) && LU.AllFixupsUnconditional)
1432 if (LU.Kind == LSRUse::ICmpZero &&
F.countsDownToZero() &&
1433 HardwareLoopProfitable)
1435 C.AddRecCost += LoopCost;
1439 const SCEV *StepReg = AR->getOperand(1);
1444 auto IsVScaleStep = [](
const SCEV *
Reg,
const TargetTransformInfo *
TTI) {
1450 if (!Regs.
count(StepReg) && !IsVScaleStep(StepReg,
TTI)) {
1451 RateRegister(
F, StepReg, Regs, LU, HardwareLoopProfitable);
1463 C.SetupCost = std::min<unsigned>(
C.SetupCost, 1 << 16);
1472void Cost::RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1473 SmallPtrSetImpl<const SCEV *> &Regs,
1474 const LSRUse &LU,
bool HardwareLoopProfitable,
1475 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1476 if (LoserRegs && LoserRegs->
count(
Reg)) {
1481 RateRegister(
F,
Reg, Regs, LU, HardwareLoopProfitable);
1482 if (LoserRegs && isLoser())
1487void Cost::RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1488 const DenseSet<const SCEV *> &VisitedRegs,
1489 const LSRUse &LU,
bool HardwareLoopProfitable,
1490 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1493 assert(
F.isCanonical(*L) &&
"Cost is accurate only for canonical formula");
1495 unsigned PrevAddRecCost =
C.AddRecCost;
1496 unsigned PrevNumRegs =
C.NumRegs;
1497 unsigned PrevNumBaseAdds =
C.NumBaseAdds;
1498 if (
const SCEV *ScaledReg =
F.ScaledReg) {
1499 if (VisitedRegs.
count(ScaledReg)) {
1503 RatePrimaryRegister(
F, ScaledReg, Regs, LU, HardwareLoopProfitable,
1508 for (
const SCEV *BaseReg :
F.BaseRegs) {
1509 if (VisitedRegs.
count(BaseReg)) {
1513 RatePrimaryRegister(
F, BaseReg, Regs, LU, HardwareLoopProfitable,
1520 size_t NumBaseParts =
F.getNumRegs();
1521 if (NumBaseParts > 1)
1526 C.NumBaseAdds += (
F.UnfoldedOffset.isNonZero());
1532 for (
const LSRFixup &
Fixup : LU.Fixups) {
1533 if (
Fixup.Offset.isCompatibleImmediate(
F.BaseOffset)) {
1534 Immediate
Offset =
Fixup.Offset.addUnsigned(
F.BaseOffset);
1538 else if (
Offset.isNonZero())
1540 APInt(64,
Offset.getKnownMinValue(),
true).getSignificantBits();
1544 if (LU.Kind == LSRUse::Address &&
Offset.isNonZero() &&
1555 if (!
valueOr(Opts->lsr_insns_cost,
true)) {
1565 if (
C.NumRegs > TTIRegNum) {
1568 if (PrevNumRegs > TTIRegNum)
1569 C.Insns += (
C.NumRegs - PrevNumRegs);
1571 C.Insns += (
C.NumRegs - TTIRegNum);
1584 if (LU.Kind == LSRUse::ICmpZero && !
F.hasZeroEnd() &&
1588 C.Insns += (
C.AddRecCost - PrevAddRecCost);
1591 if (LU.Kind != LSRUse::ICmpZero)
1592 C.Insns +=
C.NumBaseAdds - PrevNumBaseAdds;
1598 C.Insns = std::numeric_limits<unsigned>::max();
1599 C.NumRegs = std::numeric_limits<unsigned>::max();
1600 C.AddRecCost = std::numeric_limits<unsigned>::max();
1601 C.NumIVMuls = std::numeric_limits<unsigned>::max();
1602 C.NumBaseAdds = std::numeric_limits<unsigned>::max();
1603 C.ImmCost = std::numeric_limits<unsigned>::max();
1604 C.SetupCost = std::numeric_limits<unsigned>::max();
1605 C.ScaleCost = std::numeric_limits<unsigned>::max();
1609bool Cost::isLess(
const Cost &
Other)
const {
1610 if (Opts->lsr_insns_cost == BoolOrDefault::True &&
C.Insns !=
Other.C.Insns)
1611 return C.Insns <
Other.C.Insns;
1615#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1617 if (
valueOr(Opts->lsr_insns_cost,
true))
1618 OS <<
C.Insns <<
" instruction" << (
C.Insns == 1 ?
" " :
"s ");
1619 OS <<
C.NumRegs <<
" reg" << (
C.NumRegs == 1 ?
"" :
"s");
1620 if (
C.AddRecCost != 0)
1621 OS <<
", with addrec cost " <<
C.AddRecCost;
1622 if (
C.NumIVMuls != 0)
1623 OS <<
", plus " <<
C.NumIVMuls <<
" IV mul"
1624 << (
C.NumIVMuls == 1 ?
"" :
"s");
1625 if (
C.NumBaseAdds != 0)
1626 OS <<
", plus " <<
C.NumBaseAdds <<
" base add"
1627 << (
C.NumBaseAdds == 1 ?
"" :
"s");
1628 if (
C.ScaleCost != 0)
1629 OS <<
", plus " <<
C.ScaleCost <<
" scale cost";
1631 OS <<
", plus " <<
C.ImmCost <<
" imm cost";
1632 if (
C.SetupCost != 0)
1633 OS <<
", plus " <<
C.SetupCost <<
" setup cost";
1642bool LSRFixup::isUseFullyOutsideLoop(
const Loop *L)
const {
1645 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1646 if (PN->getIncomingValue(i) == OperandValToReplace &&
1647 L->contains(PN->getIncomingBlock(i)))
1652 return !
L->contains(UserInst);
1655#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1656void LSRFixup::print(raw_ostream &OS)
const {
1661 Store->getOperand(0)->printAsOperand(OS,
false);
1667 OS <<
", OperandValToReplace=";
1670 for (
const Loop *PIL : PostIncLoops) {
1671 OS <<
", PostIncLoop=";
1672 PIL->getHeader()->printAsOperand(OS,
false);
1676 OS <<
", Offset=" <<
Offset;
1686bool LSRUse::HasFormulaWithSameRegs(
const Formula &
F)
const {
1688 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1695float LSRUse::getNotSelectedProbability(
const SCEV *
Reg)
const {
1697 for (
const Formula &
F : Formulae)
1698 if (
F.referencesReg(
Reg))
1700 return ((
float)(Formulae.size() - FNum)) / Formulae.size();
1705bool LSRUse::InsertFormula(
const Formula &
F,
const Loop &L) {
1706 assert(
F.isCanonical(L) &&
"Invalid canonical representation");
1708 if (!Formulae.empty() && RigidFormula)
1712 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1720 assert((!
F.ScaledReg || !
F.ScaledReg->isZero()) &&
1721 "Zero allocated in a scaled register!");
1723 for (
const SCEV *BaseReg :
F.BaseRegs)
1724 assert(!
BaseReg->isZero() &&
"Zero allocated in a base register!");
1728 Formulae.push_back(
F);
1739void LSRUse::DeleteFormula(Formula &
F) {
1740 if (&
F != &Formulae.back())
1742 Formulae.pop_back();
1746void LSRUse::RecomputeRegs(
size_t LUIdx, RegUseTracker &RegUses) {
1748 SmallPtrSet<const SCEV *, 4> OldRegs = std::move(Regs);
1750 for (
const Formula &
F : Formulae) {
1751 if (
F.ScaledReg) Regs.
insert(
F.ScaledReg);
1756 for (
const SCEV *S : OldRegs)
1758 RegUses.dropRegister(S, LUIdx);
1761#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1762void LSRUse::print(raw_ostream &OS)
const {
1763 OS <<
"LSR Use: Kind=";
1765 case Basic: OS <<
"Basic";
break;
1766 case Special: OS <<
"Special";
break;
1767 case ICmpZero: OS <<
"ICmpZero";
break;
1769 OS <<
"Address of ";
1773 OS << *AccessTy.MemTy;
1776 OS <<
" in addrspace(" << AccessTy.AddrSpace <<
')';
1779 OS <<
", Offsets={";
1780 bool NeedComma =
false;
1781 for (
const LSRFixup &
Fixup : Fixups) {
1782 if (NeedComma) OS <<
',';
1788 if (AllFixupsOutsideLoop)
1789 OS <<
", all-fixups-outside-loop";
1791 if (AllFixupsUnconditional)
1792 OS <<
", all-fixups-unconditional";
1801 LSRUse::KindType Kind, MemAccessTy AccessTy,
1803 bool HasBaseReg, int64_t Scale,
1806 case LSRUse::Address: {
1807 int64_t FixedOffset =
1808 BaseOffset.isScalable() ? 0 : BaseOffset.getFixedValue();
1809 int64_t ScalableOffset =
1810 BaseOffset.isScalable() ? BaseOffset.getKnownMinValue() : 0;
1811 return TTI.isLegalAddressingMode(AccessTy.MemTy, BaseGV, FixedOffset,
1812 HasBaseReg, Scale, AccessTy.AddrSpace,
1813 Fixup, ScalableOffset);
1815 case LSRUse::ICmpZero:
1822 if (Scale != 0 && HasBaseReg && BaseOffset.isNonZero())
1827 if (Scale != 0 && Scale != -1)
1832 if (BaseOffset.isNonZero()) {
1835 if (BaseOffset.isScalable())
1845 BaseOffset = BaseOffset.getFixed(-(
uint64_t)BaseOffset.getFixedValue());
1846 return TTI.isLegalICmpImmediate(BaseOffset.getFixedValue());
1854 return !BaseGV && Scale == 0 && BaseOffset.isZero();
1856 case LSRUse::Special:
1858 return !BaseGV && (Scale == 0 || Scale == -1) && BaseOffset.isZero();
1865 Immediate MinOffset, Immediate MaxOffset,
1866 LSRUse::KindType Kind, MemAccessTy AccessTy,
1868 bool HasBaseReg, int64_t Scale) {
1869 if (BaseOffset.isNonZero() &&
1870 (BaseOffset.isScalable() != MinOffset.isScalable() ||
1871 BaseOffset.isScalable() != MaxOffset.isScalable()))
1874 int64_t
Base = BaseOffset.getKnownMinValue();
1875 int64_t Min = MinOffset.getKnownMinValue();
1876 int64_t Max = MaxOffset.getKnownMinValue();
1879 MinOffset = Immediate::get((
uint64_t)
Base + Min, MinOffset.isScalable());
1882 MaxOffset = Immediate::get((
uint64_t)
Base + Max, MaxOffset.isScalable());
1885 HasBaseReg, Scale) &&
1891 Immediate MinOffset, Immediate MaxOffset,
1892 LSRUse::KindType Kind, MemAccessTy AccessTy,
1893 const Formula &
F,
const Loop &L) {
1901 assert((
F.isCanonical(L) ||
F.Scale != 0));
1903 F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
F.Scale);
1908 Immediate MaxOffset, LSRUse::KindType Kind,
1910 Immediate BaseOffset,
bool HasBaseReg, int64_t Scale) {
1913 BaseOffset, HasBaseReg, Scale) ||
1918 BaseGV, BaseOffset,
true, 0));
1922 Immediate MaxOffset, LSRUse::KindType Kind,
1923 MemAccessTy AccessTy,
const Formula &
F) {
1924 return isLegalUse(
TTI, MinOffset, MaxOffset, Kind, AccessTy,
F.BaseGV,
1925 F.BaseOffset,
F.HasBaseReg,
F.Scale);
1931 return TTI.isLegalAddScalableImmediate(
Offset.getKnownMinValue());
1933 return TTI.isLegalAddImmediate(
Offset.getFixedValue());
1937 const LSRUse &LU,
const Formula &
F) {
1939 if (LU.Kind == LSRUse::Address &&
TTI.LSRWithInstrQueries()) {
1940 for (
const LSRFixup &
Fixup : LU.Fixups)
1942 (
F.BaseOffset +
Fixup.Offset),
F.HasBaseReg,
1943 F.Scale,
Fixup.UserInst))
1949 LU.AccessTy,
F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
1954 const LSRUse &LU,
const Formula &
F,
1963 return F.Scale != 1;
1966 case LSRUse::Address: {
1968 int64_t ScalableMin = 0, ScalableMax = 0, FixedMin = 0, FixedMax = 0;
1969 if (
F.BaseOffset.isScalable()) {
1970 ScalableMin = (
F.BaseOffset + LU.MinOffset).getKnownMinValue();
1971 ScalableMax = (
F.BaseOffset + LU.MaxOffset).getKnownMinValue();
1973 FixedMin = (
F.BaseOffset + LU.MinOffset).getFixedValue();
1974 FixedMax = (
F.BaseOffset + LU.MaxOffset).getFixedValue();
1978 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1981 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1984 "Legal addressing mode has an illegal cost!");
1985 return std::max(ScaleCostMinOffset, ScaleCostMaxOffset);
1987 case LSRUse::ICmpZero:
1989 case LSRUse::Special:
2000 LSRUse::KindType Kind, MemAccessTy AccessTy,
2004 if (BaseOffset.isZero() && !BaseGV)
2009 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2013 if (!HasBaseReg && Scale == 1) {
2023 if (HasBaseReg && BaseOffset.isNonZero() && Kind != LSRUse::ICmpZero &&
2025 Opts.lsr_drop_scaled_reg_for_vscale)
2035 Immediate MaxOffset, LSRUse::KindType Kind,
2036 MemAccessTy AccessTy,
const SCEV *S,
2039 if (S->
isZero())
return true;
2052 if (BaseOffset.isZero() && !BaseGV)
2055 if (BaseOffset.isScalable())
2060 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2063 BaseOffset, HasBaseReg, Scale);
2080 const SCEV *IncExpr;
2082 IVInc(Instruction *U,
Value *O,
const SCEV *
E)
2083 : UserInst(
U), IVOperand(
O), IncExpr(
E) {}
2090 const SCEV *ExprBase =
nullptr;
2092 IVChain() =
default;
2093 IVChain(
const IVInc &Head,
const SCEV *
Base)
2094 : Incs(1, Head), ExprBase(
Base) {}
2099 const_iterator
begin()
const {
2101 return std::next(Incs.
begin());
2103 const_iterator
end()
const {
2108 bool hasIncs()
const {
return Incs.
size() >= 2; }
2117 bool isProfitableIncrement(
const SCEV *OperExpr,
2118 const SCEV *IncExpr,
2126 SmallPtrSet<Instruction*, 4> FarUsers;
2127 SmallPtrSet<Instruction*, 4> NearUsers;
2132 const ScalarOptions &Opts;
2134 ScalarEvolution &SE;
2137 AssumptionCache &AC;
2138 TargetLibraryInfo &TLI;
2139 const TargetTransformInfo &
TTI;
2141 MemorySSAUpdater *MSSAU;
2145 bool HardwareLoopProfitable =
false;
2146 bool ShouldPreserveLCSSA =
false;
2160 SetVector<int64_t, SmallVector<int64_t, 8>, SmallSet<int64_t, 8>> Factors;
2167 SmallSetVector<Type *, 4> Types;
2173 RegUseTracker RegUses;
2178 static const unsigned MaxChains = 8;
2184 SmallPtrSet<Use*, MaxChains> IVIncSet;
2187 SmallVector<llvm::WeakVH, 2> ScalarEvolutionIVs;
2193 SmallSetVector<Instruction *, 4> InsertedNonLCSSAInsts;
2195 void OptimizeShadowIV();
2196 bool FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse);
2198 void OptimizeLoopTermCond();
2200 void ChainInstruction(Instruction *UserInst, Instruction *IVOper,
2201 SmallVectorImpl<ChainUsers> &ChainUsersVec);
2202 void FinalizeChain(IVChain &Chain);
2203 void CollectChains();
2204 void GenerateIVChain(
const IVChain &Chain,
2205 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2207 void CollectInterestingTypesAndFactors();
2208 void CollectFixupsAndInitialFormulae();
2211 using UseMapTy = DenseMap<LSRUse::SCEVUseKindPair, size_t>;
2214 bool reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
bool HasBaseReg,
2215 LSRUse::KindType Kind, MemAccessTy AccessTy);
2217 std::pair<size_t, Immediate> getUse(
const SCEV *&Expr, LSRUse::KindType Kind,
2218 MemAccessTy AccessTy);
2220 void DeleteUse(LSRUse &LU,
size_t LUIdx);
2222 LSRUse *FindUseWithSimilarFormula(
const Formula &
F,
const LSRUse &OrigLU);
2224 void InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2225 void InsertSupplementalFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2226 void CountRegisters(
const Formula &
F,
size_t LUIdx);
2227 bool InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F);
2228 bool IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const;
2230 void CollectLoopInvariantFixupsAndFormulae();
2232 void GenerateReassociations(LSRUse &LU,
unsigned LUIdx, Formula
Base,
2233 unsigned Depth = 0);
2235 void GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
2237 size_t Idx,
bool IsScaledReg =
false);
2238 void GenerateCombinations(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2239 void GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2240 const Formula &
Base,
size_t Idx,
2241 bool IsScaledReg =
false);
2242 void GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2243 void GenerateConstantOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2244 const Formula &
Base,
2245 const SmallVectorImpl<Immediate> &Worklist,
2246 size_t Idx,
bool IsScaledReg =
false);
2247 void GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2248 void GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2249 void GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2250 void GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2251 void GenerateCrossUseConstantOffsets();
2252 void GenerateAllReuseFormulae();
2254 void FilterOutUndesirableDedicatedRegisters();
2256 size_t EstimateSearchSpaceComplexity()
const;
2257 void NarrowSearchSpaceByDetectingSupersets();
2258 void NarrowSearchSpaceByCollapsingUnrolledCode();
2259 void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
2260 void NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
2261 void NarrowSearchSpaceByFilterPostInc();
2262 void NarrowSearchSpaceByMergingUsesOutsideLoop();
2263 void NarrowSearchSpaceByDeletingCostlyFormulas();
2264 void NarrowSearchSpaceByPickingWinnerRegs();
2265 void NarrowSearchSpaceUsingHeuristics();
2267 void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
2269 SmallVectorImpl<const Formula *> &Workspace,
2270 const Cost &CurCost,
2271 const SmallPtrSet<const SCEV *, 16> &CurRegs,
2272 DenseSet<const SCEV *> &VisitedRegs)
const;
2273 void Solve(SmallVectorImpl<const Formula *> &Solution)
const;
2277 const SmallVectorImpl<Instruction *> &Inputs)
const;
2280 const LSRUse &LU)
const;
2282 Value *Expand(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2284 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const;
2285 void RewriteForPHI(PHINode *PN,
const LSRUse &LU,
const LSRFixup &LF,
2287 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2288 void Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2289 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2290 void ImplementSolution(
const SmallVectorImpl<const Formula *> &Solution);
2297 LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
2298 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
2299 const TargetTransformInfo &
TTI, AssumptionCache &AC,
2300 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
2301 bool PreserveLCSSA);
2303 bool getChanged()
const {
return Changed; }
2304 const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs()
const {
2305 return ScalarEvolutionIVs;
2308 void print_factors_and_types(raw_ostream &OS)
const;
2309 void print_fixups(raw_ostream &OS)
const;
2310 void print_uses(raw_ostream &OS)
const;
2311 void print(raw_ostream &OS)
const;
2319void LSRInstance::OptimizeShadowIV() {
2329 Type *DestTy =
nullptr;
2330 bool IsSigned =
false;
2346 DestTy = UCast->getDestTy();
2350 DestTy = SCast->getDestTy();
2352 if (!DestTy)
continue;
2372 if (Mantissa == -1)
continue;
2376 unsigned Entry, Latch;
2386 if (!Init)
continue;
2387 Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
2391 BinaryOperator *Incr =
2393 if (!Incr)
continue;
2394 if (Incr->
getOpcode() != Instruction::Add
2395 && Incr->
getOpcode() != Instruction::Sub)
2399 ConstantInt *
C =
nullptr;
2411 if (!
C->getValue().isStrictlyPositive())
2419 Constant *CFP = ConstantFP::get(DestTy,
C->getZExtValue());
2421 Incr->
getOpcode() == Instruction::Add ? Instruction::FAdd
2422 : Instruction::FSub,
2439bool LSRInstance::FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse) {
2440 for (IVStrideUse &U : IU)
2441 if (
U.getUser() ==
Cond) {
2499Instruction *LSRInstance::OptimizeMax(ICmpInst *
Cond, IVStrideUse *&CondUse) {
2514 const SCEV *IterationCount = SE.
getAddExpr(One, BackedgeTakenCount);
2515 if (IterationCount != SE.
getSCEV(Sel))
return Cond;
2521 const SCEVNAryExpr *
Max =
nullptr;
2523 Pred = ICmpInst::ICMP_SLE;
2526 Pred = ICmpInst::ICMP_SLT;
2529 Pred = ICmpInst::ICMP_ULT;
2538 if (
Max->getNumOperands() != 2)
2541 const SCEV *MaxLHS =
Max->getOperand(0);
2542 const SCEV *MaxRHS =
Max->getOperand(1);
2547 (ICmpInst::isTrueWhenEqual(Pred) ? !MaxLHS->
isZero() : (MaxLHS != One)))
2558 "Loop condition operand is an addrec in a different loop!");
2562 Value *NewRHS =
nullptr;
2563 if (ICmpInst::isTrueWhenEqual(Pred)) {
2567 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2568 NewRHS = BO->getOperand(0);
2571 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2572 NewRHS = BO->getOperand(0);
2580 NewRHS = SU->getValue();
2592 ICmpInst *NewCond =
new ICmpInst(
Cond->getIterator(), Pred,
2593 Cond->getOperand(0), NewRHS,
"scmp");
2597 Cond->replaceAllUsesWith(NewCond);
2600 Cond->eraseFromParent();
2602 if (
Cmp->use_empty()) {
2604 Cmp->eraseFromParent();
2611LSRInstance::OptimizeLoopTermCond() {
2612 SmallPtrSet<Instruction *, 4> PostIncs;
2627 SmallVector<BasicBlock*, 8> ExitingBlocks;
2628 L->getExitingBlocks(ExitingBlocks);
2636 for (BasicBlock *ExitingBlock : ExitingBlocks) {
2658 IVStrideUse *CondUse =
nullptr;
2659 if (!FindIVUserForCond(
Cond, CondUse))
2669 Cond = OptimizeMax(Cmp, CondUse);
2674 if (!DT.
dominates(ExitingBlock, LatchBlock))
2679 if (LatchBlock != ExitingBlock)
2680 for (
const IVStrideUse &UI : IU)
2683 if (&UI != CondUse &&
2687 const SCEV *
A = IU.getStride(*CondUse, L);
2688 const SCEV *
B = IU.getStride(UI, L);
2689 if (!
A || !
B)
continue;
2698 if (
const SCEVConstant *
D =
2700 const ConstantInt *
C =
D->getValue();
2702 if (
C->isOne() ||
C->isMinusOne())
2703 goto decline_post_inc;
2705 if (
C->getValue().getSignificantBits() >= 64 ||
2706 C->getValue().isMinSignedValue())
2707 goto decline_post_inc;
2710 MemAccessTy AccessTy =
2712 int64_t Scale =
C->getSExtValue();
2716 AccessTy.AddrSpace))
2717 goto decline_post_inc;
2722 AccessTy.AddrSpace))
2723 goto decline_post_inc;
2728 LLVM_DEBUG(
dbgs() <<
" Change loop exiting icmp to use postinc iv: "
2736 if (
Cond->hasOneUse()) {
2742 Cond->setName(
L->getHeader()->getName() +
".termcond");
2764 IVIncInsertPos =
L->getLoopLatch()->getTerminator();
2765 for (Instruction *Inst : PostIncs)
2771bool LSRInstance::reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
2772 bool HasBaseReg, LSRUse::KindType Kind,
2773 MemAccessTy AccessTy) {
2774 Immediate NewMinOffset = LU.MinOffset;
2775 Immediate NewMaxOffset = LU.MaxOffset;
2776 MemAccessTy NewAccessTy = AccessTy;
2781 if (LU.Kind != Kind)
2787 if (Kind == LSRUse::Address) {
2788 if (AccessTy.MemTy != LU.AccessTy.MemTy) {
2789 NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->
getContext(),
2790 AccessTy.AddrSpace);
2795 if (Immediate::isKnownLT(NewOffset, LU.MinOffset)) {
2797 LU.MaxOffset - NewOffset, HasBaseReg))
2799 NewMinOffset = NewOffset;
2800 }
else if (Immediate::isKnownGT(NewOffset, LU.MaxOffset)) {
2802 NewOffset - LU.MinOffset, HasBaseReg))
2804 NewMaxOffset = NewOffset;
2810 if (NewAccessTy.MemTy && NewAccessTy.MemTy->
isVoidTy() &&
2811 (NewMinOffset.isScalable() || NewMaxOffset.isScalable()))
2815 LU.MinOffset = NewMinOffset;
2816 LU.MaxOffset = NewMaxOffset;
2817 LU.AccessTy = NewAccessTy;
2824std::pair<size_t, Immediate> LSRInstance::getUse(
const SCEV *&Expr,
2825 LSRUse::KindType Kind,
2826 MemAccessTy AccessTy) {
2827 const SCEV *
Copy = Expr;
2830 Opts, ExprUse, SE, AccessTy.MemTy && AccessTy.MemTy->
isScalableTy());
2837 Offset = Immediate::getFixed(0);
2840 std::pair<UseMapTy::iterator, bool>
P =
2841 UseMap.
try_emplace(LSRUse::SCEVUseKindPair(Expr, Kind));
2844 size_t LUIdx =
P.first->second;
2845 LSRUse &LU =
Uses[LUIdx];
2846 if (reconcileNewOffset(LU,
Offset,
true, Kind, AccessTy))
2848 return std::make_pair(LUIdx,
Offset);
2852 size_t LUIdx =
Uses.size();
2853 P.first->second = LUIdx;
2854 Uses.push_back(LSRUse(Kind, AccessTy));
2855 LSRUse &LU =
Uses[LUIdx];
2859 return std::make_pair(LUIdx,
Offset);
2863void LSRInstance::DeleteUse(LSRUse &LU,
size_t LUIdx) {
2864 if (&LU != &
Uses.back())
2869 RegUses.swapAndDropUse(LUIdx,
Uses.size());
2875LSRInstance::FindUseWithSimilarFormula(
const Formula &OrigF,
2876 const LSRUse &OrigLU) {
2878 for (LSRUse &LU :
Uses) {
2884 if (&LU != &OrigLU && LU.Kind != LSRUse::ICmpZero &&
2885 LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
2886 LU.HasFormulaWithSameRegs(OrigF)) {
2888 for (
const Formula &
F : LU.Formulae) {
2891 if (
F.BaseRegs == OrigF.BaseRegs &&
2892 F.ScaledReg == OrigF.ScaledReg &&
2893 F.BaseGV == OrigF.BaseGV &&
2894 F.Scale == OrigF.Scale &&
2895 F.UnfoldedOffset == OrigF.UnfoldedOffset) {
2896 if (
F.BaseOffset.isZero())
2911void LSRInstance::CollectInterestingTypesAndFactors() {
2912 SmallSetVector<const SCEV *, 4> Strides;
2916 for (
const IVStrideUse &U : IU) {
2917 const SCEV *Expr = IU.getExpr(U);
2935 }
while (!Worklist.
empty());
2939 for (SmallSetVector<const SCEV *, 4>::const_iterator
2941 for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
2942 std::next(
I); NewStrideIter !=
E; ++NewStrideIter) {
2943 const SCEV *OldStride = *
I;
2944 const SCEV *NewStride = *NewStrideIter;
2954 if (
const SCEVConstant *Factor =
2957 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
2958 Factors.insert(Factor->getAPInt().getSExtValue());
2959 }
else if (
const SCEVConstant *Factor =
2963 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
2964 Factors.insert(Factor->getAPInt().getSExtValue());
2970 if (Types.size() == 1)
2982 for(; OI != OE; ++OI) {
3001 return Trunc->getOperand(0);
3034 if (SubExpr->getSCEVType() ==
scAddExpr)
3037 if (SubExpr->getSCEVType() !=
scMulExpr)
3053bool IVChain::isProfitableIncrement(
const SCEV *OperExpr,
3054 const SCEV *IncExpr,
3055 ScalarEvolution &SE) {
3064 SmallPtrSet<const SCEV*, 8> Processed;
3082 if (!Chain.hasIncs())
3085 if (!
Users.empty()) {
3086 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" users:\n";
3088 :
Users) {
dbgs() <<
" " << *Inst <<
"\n"; });
3091 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3100 && SE.
getSCEV(Chain.tailUserInst()) == Chain.Incs[0].IncExpr) {
3103 const SCEV *LastIncExpr =
nullptr;
3104 unsigned NumConstIncrements = 0;
3105 unsigned NumVarIncrements = 0;
3106 unsigned NumReusedIncrements = 0;
3108 if (
TTI.isProfitableLSRChainElement(Chain.Incs[0].UserInst))
3111 for (
const IVInc &Inc : Chain) {
3112 if (
TTI.isProfitableLSRChainElement(Inc.UserInst))
3114 if (Inc.IncExpr->isZero())
3120 ++NumConstIncrements;
3124 if (Inc.IncExpr == LastIncExpr)
3125 ++NumReusedIncrements;
3129 LastIncExpr = Inc.IncExpr;
3134 if (NumConstIncrements > 1)
3141 cost += NumVarIncrements;
3145 cost -= NumReusedIncrements;
3147 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" Cost: " << cost
3154void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
3155 SmallVectorImpl<ChainUsers> &ChainUsersVec) {
3159 const SCEV *
const OperExpr = SE.
getSCEV(NextIV);
3160 const SCEV *
const OperExprBase =
getExprBase(OperExpr);
3164 unsigned ChainIdx = 0, NChains = IVChainVec.size();
3165 const SCEV *LastIncExpr =
nullptr;
3166 for (; ChainIdx < NChains; ++ChainIdx) {
3167 IVChain &Chain = IVChainVec[ChainIdx];
3185 const SCEV *PrevExpr = SE.
getSCEV(PrevIV);
3186 const SCEV *IncExpr = SE.
getMinusSCEV(OperExpr, PrevExpr);
3192 Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
3193 LastIncExpr = IncExpr;
3199 if (ChainIdx == NChains) {
3206 LastIncExpr = OperExpr;
3213 IVChainVec.push_back(IVChain(IVInc(UserInst, IVOper, LastIncExpr),
3215 ChainUsersVec.
resize(NChains);
3216 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Head: (" << *UserInst
3217 <<
") IV=" << *LastIncExpr <<
"\n");
3219 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Inc: (" << *UserInst
3220 <<
") IV+" << *LastIncExpr <<
"\n");
3222 IVChainVec[ChainIdx].add(IVInc(UserInst, IVOper, LastIncExpr));
3224 IVChain &Chain = IVChainVec[ChainIdx];
3226 SmallPtrSet<Instruction*,4> &NearUsers = ChainUsersVec[ChainIdx].NearUsers;
3228 if (!LastIncExpr->
isZero()) {
3229 ChainUsersVec[ChainIdx].FarUsers.insert_range(NearUsers);
3238 for (User *U : IVOper->
users()) {
3244 IVChain::const_iterator IncIter = Chain.Incs.begin();
3245 IVChain::const_iterator IncEnd = Chain.Incs.end();
3246 for( ; IncIter != IncEnd; ++IncIter) {
3247 if (IncIter->UserInst == OtherUse)
3250 if (IncIter != IncEnd)
3255 && IU.isIVUserOrOperand(OtherUse)) {
3258 NearUsers.
insert(OtherUse);
3263 ChainUsersVec[ChainIdx].FarUsers.
erase(UserInst);
3288void LSRInstance::CollectChains() {
3292 SmallVector<BasicBlock *,8> LatchPath;
3295 Rung->
getBlock() != LoopHeader; Rung = Rung->getIDom()) {
3301 for (BasicBlock *BB :
reverse(LatchPath)) {
3302 for (Instruction &
I : *BB) {
3308 if (IU.isEphemeral(&
I))
3318 for (
unsigned ChainIdx = 0, NChains = IVChainVec.size();
3319 ChainIdx < NChains; ++ChainIdx) {
3320 ChainUsersVec[ChainIdx].NearUsers.
erase(&
I);
3323 SmallPtrSet<Instruction*, 4> UniqueOperands;
3326 while (IVOpIter != IVOpEnd) {
3328 if (UniqueOperands.
insert(IVOpInst).second)
3329 ChainInstruction(&
I, IVOpInst, ChainUsersVec);
3330 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3335 for (PHINode &PN :
L->getHeader()->phis()) {
3342 ChainInstruction(&PN, IncV, ChainUsersVec);
3345 unsigned ChainIdx = 0;
3346 for (
unsigned UsersIdx = 0, NChains = IVChainVec.size();
3347 UsersIdx < NChains; ++UsersIdx) {
3350 ChainUsersVec[UsersIdx].FarUsers, SE,
TTI))
3353 if (ChainIdx != UsersIdx)
3354 IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
3355 FinalizeChain(IVChainVec[ChainIdx]);
3358 IVChainVec.resize(ChainIdx);
3361void LSRInstance::FinalizeChain(IVChain &Chain) {
3362 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3363 LLVM_DEBUG(
dbgs() <<
"Final Chain: " << *Chain.Incs[0].UserInst <<
"\n");
3365 for (
const IVInc &Inc : Chain) {
3367 auto UseI =
find(Inc.UserInst->operands(), Inc.IVOperand);
3368 assert(UseI != Inc.UserInst->op_end() &&
"cannot find IV operand");
3369 IVIncSet.insert(UseI);
3378 Immediate IncOffset = Immediate::getZero();
3387 C->getSignificantBits() > 64)
3389 IncOffset = Immediate::getScalable(
C->getSExtValue());
3397 nullptr, IncOffset,
false))
3405void LSRInstance::GenerateIVChain(
const IVChain &Chain,
3406 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
3409 const IVInc &Head = Chain.Incs[0];
3414 Value *IVSrc =
nullptr;
3415 while (IVOpIter != IVOpEnd) {
3426 if (SE.
getSCEV(*IVOpIter) == Head.IncExpr
3427 || SE.
getSCEV(IVSrc) == Head.IncExpr) {
3430 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3432 if (IVOpIter == IVOpEnd) {
3434 LLVM_DEBUG(
dbgs() <<
"Concealed chain head: " << *Head.UserInst <<
"\n");
3437 assert(IVSrc &&
"Failed to find IV chain source");
3442 const SCEV *LeftOverExpr =
nullptr;
3443 const SCEV *Accum = SE.
getZero(IntTy);
3447 for (
const IVInc &Inc : Chain) {
3450 InsertPt =
L->getLoopLatch()->getTerminator();
3454 Value *IVOper = IVSrc;
3455 if (!Inc.IncExpr->isZero()) {
3460 LeftOverExpr = LeftOverExpr
3466 bool FoundBase =
false;
3467 for (
auto [MapScev, MapIVOper] :
reverse(Bases)) {
3468 const SCEV *Remainder = SE.
getMinusSCEV(Accum, MapScev);
3470 if (!Remainder->
isZero()) {
3472 Value *IncV =
Rewriter.expandCodeFor(Remainder, IntTy, InsertPt);
3473 const SCEV *IVOperExpr =
3475 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3484 if (!FoundBase && LeftOverExpr && !LeftOverExpr->
isZero()) {
3487 Value *IncV =
Rewriter.expandCodeFor(LeftOverExpr, IntTy, InsertPt);
3490 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3495 assert(IVTy == IVOper->
getType() &&
"inconsistent IV increment type");
3498 LeftOverExpr =
nullptr;
3502 if (IVTy != OperTy) {
3504 "cannot extend a chained IV");
3506 IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy,
"lsr.chain");
3508 Inc.UserInst->replaceUsesOfWith(Inc.IVOperand, IVOper);
3515 for (PHINode &Phi :
L->getHeader()->phis()) {
3519 Phi.getIncomingValueForBlock(
L->getLoopLatch()));
3522 Value *IVOper = IVSrc;
3524 if (IVTy != PostIncTy) {
3526 IRBuilder<> Builder(
L->getLoopLatch()->getTerminator());
3527 Builder.SetCurrentDebugLocation(PostIncV->
getDebugLoc());
3528 IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy,
"lsr.chain");
3530 Phi.replaceUsesOfWith(PostIncV, IVOper);
3536void LSRInstance::CollectFixupsAndInitialFormulae() {
3537 CondBrInst *ExitBranch =
nullptr;
3538 bool SaveCmp =
TTI.
canSaveCmp(L, &ExitBranch, &SE, &LI, &DT, &AC, &TLI);
3541 SmallPtrSet<const SCEV *, 16> Regs;
3542 DenseSet<const SCEV *> VisitedRegs;
3543 DenseSet<size_t> VisitedLSRUse;
3545 for (
const IVStrideUse &U : IU) {
3550 assert(UseI != UserInst->
op_end() &&
"cannot find IV operand");
3551 if (IVIncSet.count(UseI)) {
3552 LLVM_DEBUG(
dbgs() <<
"Use is in profitable chain: " << **UseI <<
'\n');
3556 LSRUse::KindType
Kind = LSRUse::Basic;
3557 MemAccessTy AccessTy;
3559 Kind = LSRUse::Address;
3563 const SCEV *S = IU.getExpr(U);
3579 if (CI->isEquality()) {
3582 Value *
NV = CI->getOperand(1);
3583 if (NV ==
U.getOperandValToReplace()) {
3584 CI->setOperand(1, CI->getOperand(0));
3585 CI->setOperand(0, NV);
3586 NV = CI->getOperand(1);
3593 (!
NV->getType()->isPointerTy() ||
3600 Kind = LSRUse::ICmpZero;
3602 }
else if (
L->isLoopInvariant(NV) &&
3605 !
NV->getType()->isPointerTy()) {
3616 Kind = LSRUse::ICmpZero;
3623 for (
size_t i = 0, e = Factors.size(); i != e; ++i)
3624 if (Factors[i] != -1)
3625 Factors.insert(-(
uint64_t)Factors[i]);
3631 std::pair<size_t, Immediate>
P = getUse(S, Kind, AccessTy);
3632 size_t LUIdx =
P.first;
3634 LSRUse &LU =
Uses[LUIdx];
3637 LSRFixup &LF = LU.getNewFixup();
3638 LF.UserInst = UserInst;
3639 LF.OperandValToReplace =
U.getOperandValToReplace();
3640 LF.PostIncLoops = TmpPostIncLoops;
3642 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3643 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3646 if (!VisitedLSRUse.
count(LUIdx) && !LF.isUseFullyOutsideLoop(L)) {
3648 F.initialMatch(S, L, SE);
3649 BaselineCost.RateFormula(
F, Regs, VisitedRegs, LU,
3650 HardwareLoopProfitable);
3651 VisitedLSRUse.
insert(LUIdx);
3655 if (LU.Formulae.empty()) {
3656 InsertInitialFormula(S, LU, LUIdx);
3657 CountRegisters(LU.Formulae.back(), LUIdx);
3666void LSRInstance::InsertInitialFormula(
const SCEV *S, LSRUse &LU,
3670 LU.RigidFormula =
true;
3673 F.initialMatch(S, L, SE);
3674 bool Inserted = InsertFormula(LU, LUIdx,
F);
3675 assert(Inserted &&
"Initial formula already exists!"); (void)Inserted;
3681LSRInstance::InsertSupplementalFormula(
const SCEV *S,
3682 LSRUse &LU,
size_t LUIdx) {
3684 F.BaseRegs.push_back(S);
3685 F.HasBaseReg =
true;
3686 bool Inserted = InsertFormula(LU, LUIdx,
F);
3687 assert(Inserted &&
"Supplemental formula already exists!"); (void)Inserted;
3691void LSRInstance::CountRegisters(
const Formula &
F,
size_t LUIdx) {
3693 RegUses.countRegister(
F.ScaledReg, LUIdx);
3694 for (
const SCEV *BaseReg :
F.BaseRegs)
3695 RegUses.countRegister(BaseReg, LUIdx);
3700bool LSRInstance::InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F) {
3703 "Formula is illegal");
3705 if (!LU.InsertFormula(
F, *L))
3708 CountRegisters(
F, LUIdx);
3714bool LSRInstance::IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const {
3726LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
3728 SmallPtrSet<const SCEV *, 32> Visited;
3735 while (!Worklist.
empty()) {
3739 if (!Visited.
insert(S).second)
3750 const Value *
V = US->getValue();
3753 if (
L->contains(Inst))
continue;
3757 for (
const Use &U :
V->uses()) {
3767 if (UserInst->
getParent()->getParent() !=
L->getHeader()->getParent())
3789 bool HasIncompatibleEHPTerminatedBlock =
false;
3791 for (
unsigned int I = 0;
I < PhiNode->getNumIncomingValues();
I++) {
3792 if (PhiNode->getIncomingValue(
I) == ExpectedValue) {
3793 if (PhiNode->getIncomingBlock(
I)->getTerminator()->isEHPad()) {
3794 HasIncompatibleEHPTerminatedBlock =
true;
3799 if (HasIncompatibleEHPTerminatedBlock) {
3822 unsigned OtherIdx = !
U.getOperandNo();
3823 Value *OtherOp = ICI->getOperand(OtherIdx);
3833 std::pair<size_t, Immediate>
P =
3834 getUse(S, LSRUse::Basic, MemAccessTy());
3835 size_t LUIdx =
P.first;
3837 LSRUse &LU =
Uses[LUIdx];
3838 LSRFixup &LF = LU.getNewFixup();
3839 LF.UserInst =
const_cast<Instruction *
>(UserInst);
3840 LF.OperandValToReplace =
U;
3842 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3843 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3844 InsertSupplementalFormula(US, LU, LUIdx);
3845 CountRegisters(LU.Formulae.back(),
Uses.size() - 1);
3861 unsigned Depth = 0) {
3868 for (
const SCEV *S :
Add->operands()) {
3875 const SCEV *Start, *Step;
3880 if (Start->isZero())
3889 Remainder =
nullptr;
3891 if (Remainder != Start) {
3913 LSRUse &LU,
const SCEV *S,
const Loop *L,
3915 if (LU.Kind != LSRUse::Address ||
3916 !LU.AccessTy.getType()->isIntOrIntVectorTy())
3922 if (
TTI.isIndexedLoadLegal(
TTI.MIM_PostInc, S->
getType()) ||
3931void LSRInstance::GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
3932 const Formula &
Base,
3933 unsigned Depth,
size_t Idx,
3943 const SCEV *Remainder =
CollectSubexprs(BaseReg,
nullptr, AddOps, L, SE);
3947 if (AddOps.
size() == 1)
3961 LU.AccessTy, *J,
Base.getNumRegs() > 1))
3966 InnerAddOps.append(std::next(J), std::as_const(AddOps).
end());
3970 if (InnerAddOps.size() == 1 &&
3972 LU.AccessTy, InnerAddOps[0],
Base.getNumRegs() > 1))
3975 const SCEV *InnerSum = SE.
getAddExpr(InnerAddOps);
3980 if (
F.UnfoldedOffset.isNonZero() &&
F.UnfoldedOffset.isScalable())
3989 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
3992 F.ScaledReg =
nullptr;
3995 F.BaseRegs.erase(
F.BaseRegs.begin() + Idx);
3996 }
else if (IsScaledReg)
3997 F.ScaledReg = InnerSum;
3999 F.BaseRegs[
Idx] = InnerSum;
4007 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
4010 F.BaseRegs.push_back(*J);
4015 if (InsertFormula(LU, LUIdx,
F))
4022 GenerateReassociations(LU, LUIdx, LU.Formulae.back(),
4028void LSRInstance::GenerateReassociations(LSRUse &LU,
unsigned LUIdx,
4030 assert(
Base.isCanonical(*L) &&
"Input must be in the canonical form");
4035 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4036 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth, i);
4038 if (
Base.Scale == 1)
4039 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth,
4045void LSRInstance::GenerateCombinations(LSRUse &LU,
unsigned LUIdx,
4048 if (
Base.BaseRegs.size() + (
Base.Scale == 1) +
4049 (
Base.UnfoldedOffset.isNonZero()) <=
4057 Formula NewBase =
Base;
4058 NewBase.BaseRegs.clear();
4059 Type *CombinedIntegerType =
nullptr;
4060 for (
const SCEV *BaseReg :
Base.BaseRegs) {
4063 if (!CombinedIntegerType)
4065 Ops.push_back(BaseReg);
4068 NewBase.BaseRegs.push_back(BaseReg);
4072 if (
Ops.size() == 0)
4077 auto GenerateFormula = [&](
const SCEV *Sum) {
4078 Formula
F = NewBase;
4086 F.BaseRegs.push_back(Sum);
4088 (void)InsertFormula(LU, LUIdx,
F);
4092 if (
Ops.size() > 1) {
4099 if (NewBase.UnfoldedOffset.isNonZero() && NewBase.UnfoldedOffset.isFixed()) {
4100 assert(CombinedIntegerType &&
"Missing a type for the unfolded offset");
4102 NewBase.UnfoldedOffset.getFixedValue(),
true));
4103 NewBase.UnfoldedOffset = Immediate::getFixed(0);
4109void LSRInstance::GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
4110 const Formula &
Base,
size_t Idx,
4114 if (
G->isZero() || !GV)
4118 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4123 F.BaseRegs[
Idx] =
G;
4124 (void)InsertFormula(LU, LUIdx,
F);
4128void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx,
4131 if (
Base.BaseGV)
return;
4133 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4134 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, i);
4135 if (
Base.Scale == 1)
4136 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, -1,
4141void LSRInstance::GenerateConstantOffsetsImpl(
4142 LSRUse &LU,
unsigned LUIdx,
const Formula &
Base,
4143 const SmallVectorImpl<Immediate> &Worklist,
size_t Idx,
bool IsScaledReg) {
4145 auto GenerateOffset = [&](
const SCEV *
G, Immediate
Offset) {
4147 if (!
Base.BaseOffset.isCompatibleImmediate(
Offset))
4149 F.BaseOffset =
Base.BaseOffset.subUnsigned(
Offset);
4151 if (
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F)) {
4153 const SCEV *NewOffset =
Offset.getSCEV(SE,
G->getType());
4159 F.ScaledReg =
nullptr;
4161 F.deleteBaseReg(
F.BaseRegs[Idx]);
4163 }
else if (IsScaledReg)
4166 F.BaseRegs[
Idx] = NewG;
4168 (void)InsertFormula(LU, LUIdx,
F);
4183 const APInt *StepInt;
4188 for (Immediate
Offset : Worklist) {
4190 Offset = Immediate::getFixed(
Offset.getFixedValue() - Step);
4196 for (Immediate
Offset : Worklist)
4203 if (
G->isZero() ||
Imm.isZero() ||
4204 !
Base.BaseOffset.isCompatibleImmediate(
Imm))
4207 F.BaseOffset =
F.BaseOffset.addUnsigned(
Imm);
4208 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4213 F.BaseRegs[
Idx] =
G;
4218 (void)InsertFormula(LU, LUIdx,
F);
4222void LSRInstance::GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx,
4228 if (LU.MaxOffset != LU.MinOffset)
4231 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4232 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, i);
4233 if (
Base.Scale == 1)
4234 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, -1,
4240void LSRInstance::GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx,
4242 if (LU.Kind != LSRUse::ICmpZero)
return;
4250 if (LU.MinOffset != LU.MaxOffset)
return;
4253 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4255 for (
const SCEV *BaseReg :
Base.BaseRegs)
4256 if (
BaseReg->getType()->isPointerTy())
4258 assert(!
Base.BaseGV &&
"ICmpZero use is not legal!");
4261 for (int64_t Factor : Factors) {
4266 if (
Base.BaseOffset.isMin() && Factor == -1)
4269 if (
Base.BaseOffset.isNonZero() &&
Base.BaseOffset.isScalable())
4271 Immediate NewBaseOffset =
Base.BaseOffset.mulUnsigned(Factor);
4272 assert(Factor != 0 &&
"Zero factor not expected!");
4273 if (NewBaseOffset.getFixedValue() / Factor !=
4274 Base.BaseOffset.getFixedValue())
4282 Immediate
Offset = LU.MinOffset;
4283 if (
Offset.isMin() && Factor == -1)
4286 if (
Offset.getFixedValue() / Factor != LU.MinOffset.getFixedValue())
4294 F.BaseOffset = NewBaseOffset;
4301 F.BaseOffset =
F.BaseOffset.addUnsigned(
Offset).subUnsigned(LU.MinOffset);
4303 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4306 for (
size_t i = 0, e =
F.BaseRegs.size(); i != e; ++i) {
4320 if (
F.UnfoldedOffset.isNonZero()) {
4321 if (
F.UnfoldedOffset.isMin() && Factor == -1)
4323 F.UnfoldedOffset =
F.UnfoldedOffset.mulUnsigned(Factor);
4324 if (
F.UnfoldedOffset.getFixedValue() / Factor !=
4325 Base.UnfoldedOffset.getFixedValue())
4329 IntTy,
F.UnfoldedOffset.getFixedValue()))
4334 (void)InsertFormula(LU, LUIdx,
F);
4341void LSRInstance::GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4348 if (
Base.Scale != 0 && !
Base.unscale())
4351 assert(
Base.Scale == 0 &&
"unscale did not did its job!");
4354 for (int64_t Factor : Factors) {
4355 Base.Scale = Factor;
4356 Base.HasBaseReg =
Base.BaseRegs.size() > 1;
4358 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4362 if (LU.Kind == LSRUse::Basic &&
4363 isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
4364 LU.AccessTy,
Base) &&
4365 LU.AllFixupsOutsideLoop)
4366 LU.Kind = LSRUse::Special;
4372 if (LU.Kind == LSRUse::ICmpZero && !
Base.HasBaseReg &&
4373 Base.BaseOffset.isZero() && !
Base.BaseGV)
4376 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i) {
4378 if (AR && (AR->
getLoop() == L || LU.AllFixupsOutsideLoop)) {
4379 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4384 if (
const SCEV *Quotient =
getExactSDiv(AR, FactorS, SE,
true))
4385 if (!Quotient->isZero()) {
4388 F.ScaledReg = Quotient;
4389 F.deleteBaseReg(
F.BaseRegs[i]);
4393 if (
F.Scale == 1 && (
F.BaseRegs.empty() ||
4394 (AR->
getLoop() != L && LU.AllFixupsOutsideLoop)))
4398 if (
F.Scale == 1 && LU.AllFixupsOutsideLoop)
4400 (void)InsertFormula(LU, LUIdx,
F);
4416 const SCEV *Result =
nullptr;
4417 for (
auto &L :
Loops) {
4421 if (!New || (Result && New != Result))
4426 assert(Result &&
"failed to create expression");
4431void LSRInstance::GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4433 if (
Base.BaseGV)
return;
4443 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4446 [](
const SCEV *S) { return S->getType()->isPointerTy(); }))
4450 for (
auto &LF : LU.Fixups)
4451 Loops.push_back(LF.PostIncLoops);
4453 for (
Type *SrcTy : Types) {
4462 const SCEV *NewScaledReg =
4464 if (!NewScaledReg || NewScaledReg->
isZero())
4466 F.ScaledReg = NewScaledReg;
4468 bool HasZeroBaseReg =
false;
4469 for (
const SCEV *&BaseReg :
F.BaseRegs) {
4470 const SCEV *NewBaseReg =
4472 if (!NewBaseReg || NewBaseReg->
isZero()) {
4473 HasZeroBaseReg =
true;
4483 if (!
F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
4487 (void)InsertFormula(LU, LUIdx,
F);
4500 const SCEV *OrigReg;
4502 WorkItem(
size_t LI, Immediate
I,
const SCEV *R)
4503 : LUIdx(LI),
Imm(
I), OrigReg(
R) {}
4505 void print(raw_ostream &OS)
const;
4511#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4512void WorkItem::print(raw_ostream &OS)
const {
4513 OS <<
"in formulae referencing " << *OrigReg <<
" in use " << LUIdx
4514 <<
" , add offset " <<
Imm;
4524void LSRInstance::GenerateCrossUseConstantOffsets() {
4526 using ImmMapTy = std::map<Immediate, const SCEV *, KeyOrderTargetImmediate>;
4528 DenseMap<const SCEV *, ImmMapTy>
Map;
4529 DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
4531 for (
const SCEV *Use : RegUses) {
4535 auto Pair =
Map.try_emplace(
Reg);
4538 Pair.first->second.insert(std::make_pair(
Imm, Use));
4539 UsedByIndicesMap[
Reg] |= RegUses.getUsedByIndices(Use);
4546 SmallSet<std::pair<size_t, Immediate>, 32, KeyOrderSizeTAndImmediate>
4548 for (
const SCEV *
Reg : Sequence) {
4549 const ImmMapTy &Imms =
Map.find(
Reg)->second;
4552 if (Imms.size() == 1)
4556 for (
const auto &Entry
4558 <<
' ' <<
Entry.first;
4562 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
4564 const SCEV *OrigReg = J->second;
4566 Immediate JImm = J->first;
4567 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
4570 UsedByIndicesMap[
Reg].
count() == 1) {
4578 Immediate
First = Imms.begin()->first;
4579 Immediate
Last = std::prev(Imms.end())->first;
4580 if (!
First.isCompatibleImmediate(
Last)) {
4587 bool Scalable =
First.isScalable() ||
Last.isScalable();
4588 int64_t FI =
First.getKnownMinValue();
4589 int64_t LI =
Last.getKnownMinValue();
4592 int64_t Avg = (FI & LI) + ((FI ^ LI) >> 1);
4595 Avg = Avg + ((FI ^ LI) & ((
uint64_t)Avg >> 63));
4596 ImmMapTy::const_iterator OtherImms[] = {
4597 Imms.begin(), std::prev(Imms.end()),
4598 Imms.lower_bound(Immediate::get(Avg, Scalable))};
4599 for (
const auto &M : OtherImms) {
4600 if (M == J || M == JE)
continue;
4601 if (!JImm.isCompatibleImmediate(
M->first))
4605 Immediate
Imm = JImm.subUnsigned(
M->first);
4606 for (
unsigned LUIdx : UsedByIndices.
set_bits())
4608 if (UniqueItems.
insert(std::make_pair(LUIdx,
Imm)).second)
4616 UsedByIndicesMap.
clear();
4617 UniqueItems.
clear();
4620 for (
const WorkItem &WI : WorkItems) {
4621 size_t LUIdx = WI.LUIdx;
4622 LSRUse &LU =
Uses[LUIdx];
4623 Immediate
Imm = WI.Imm;
4624 const SCEV *OrigReg = WI.OrigReg;
4627 const SCEV *NegImmS =
Imm.getNegativeSCEV(SE, IntTy);
4631 for (
size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
4632 Formula
F = LU.Formulae[
L];
4639 if (
F.ScaledReg == OrigReg) {
4640 if (!
F.BaseOffset.isCompatibleImmediate(
Imm))
4642 Immediate
Offset =
F.BaseOffset.addUnsigned(
Imm.mulUnsigned(
F.Scale));
4644 const SCEV *S =
Offset.getNegativeSCEV(SE, IntTy);
4645 if (
F.referencesReg(S))
4648 NewF.BaseOffset =
Offset;
4649 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4652 NewF.ScaledReg = SE.
getAddExpr(NegImmS, NewF.ScaledReg);
4661 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4663 if (
C->getValue()->isNegative() !=
4664 (NewF.BaseOffset.isLessThanZero()) &&
4665 (
C->getAPInt().abs() * APInt(
BitWidth,
F.Scale))
4666 .ule(std::abs(NewF.BaseOffset.getFixedValue())))
4671 NewF.canonicalize(*this->L);
4672 (void)InsertFormula(LU, LUIdx, NewF);
4675 for (
size_t N = 0, NE =
F.BaseRegs.size();
N != NE; ++
N) {
4677 if (BaseReg != OrigReg)
4680 if (!NewF.BaseOffset.isCompatibleImmediate(
Imm) ||
4681 !NewF.UnfoldedOffset.isCompatibleImmediate(
Imm) ||
4682 !NewF.BaseOffset.isCompatibleImmediate(NewF.UnfoldedOffset))
4684 NewF.BaseOffset = NewF.BaseOffset.addUnsigned(
Imm);
4686 LU.Kind, LU.AccessTy, NewF)) {
4690 Immediate NewUnfoldedOffset = NewF.UnfoldedOffset.addUnsigned(
Imm);
4694 NewF.UnfoldedOffset = NewUnfoldedOffset;
4696 NewF.BaseRegs[
N] = SE.
getAddExpr(NegImmS, BaseReg);
4701 for (
const SCEV *NewReg : NewF.BaseRegs)
4703 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4705 if ((
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4707 .slt(std::abs(NewF.BaseOffset.getFixedValue())) &&
4708 (
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4711 NewF.BaseOffset.getFixedValue()))
4716 NewF.canonicalize(*this->L);
4717 (void)InsertFormula(LU, LUIdx, NewF);
4728LSRInstance::GenerateAllReuseFormulae() {
4731 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4732 LSRUse &LU =
Uses[LUIdx];
4733 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4734 GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
4735 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4736 GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
4738 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4739 LSRUse &LU =
Uses[LUIdx];
4740 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4741 GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
4742 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4743 GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
4744 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4745 GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
4746 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4747 GenerateScales(LU, LUIdx, LU.Formulae[i]);
4749 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4750 LSRUse &LU =
Uses[LUIdx];
4751 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4752 GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
4755 GenerateCrossUseConstantOffsets();
4758 "After generating reuse formulae:\n";
4759 print_uses(
dbgs()));
4764void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
4765 DenseSet<const SCEV *> VisitedRegs;
4766 SmallPtrSet<const SCEV *, 16> Regs;
4767 SmallPtrSet<const SCEV *, 16> LoserRegs;
4769 bool ChangedFormulae =
false;
4774 using BestFormulaeTy = DenseMap<SmallVector<const SCEV *, 4>,
size_t>;
4776 BestFormulaeTy BestFormulae;
4778 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4779 LSRUse &LU =
Uses[LUIdx];
4784 for (
size_t FIdx = 0, NumForms = LU.Formulae.size();
4785 FIdx != NumForms; ++FIdx) {
4786 Formula &
F = LU.Formulae[FIdx];
4795 Cost CostF(Opts, L, SE,
TTI, AMK);
4797 CostF.RateFormula(
F, Regs, VisitedRegs, LU, HardwareLoopProfitable,
4799 if (CostF.isLoser()) {
4811 for (
const SCEV *
Reg :
F.BaseRegs) {
4812 if (RegUses.isRegUsedByUsesOtherThan(
Reg, LUIdx))
4816 RegUses.isRegUsedByUsesOtherThan(
F.ScaledReg, LUIdx))
4817 Key.push_back(
F.ScaledReg);
4822 std::pair<BestFormulaeTy::const_iterator, bool>
P =
4823 BestFormulae.insert(std::make_pair(
Key, FIdx));
4827 Formula &Best = LU.Formulae[
P.first->second];
4829 Cost CostBest(Opts, L, SE,
TTI, AMK);
4831 CostBest.RateFormula(Best, Regs, VisitedRegs, LU,
4832 HardwareLoopProfitable);
4833 if (CostF.isLess(CostBest))
4837 " in favor of formula ";
4838 Best.print(
dbgs());
dbgs() <<
'\n');
4841 ChangedFormulae =
true;
4843 LU.DeleteFormula(
F);
4851 LU.RecomputeRegs(LUIdx, RegUses);
4854 BestFormulae.clear();
4859 "After filtering out undesirable candidates:\n";
4867size_t LSRInstance::EstimateSearchSpaceComplexity()
const {
4869 for (
const LSRUse &LU :
Uses) {
4870 size_t FSize = LU.Formulae.size();
4871 if (FSize >= Opts.lsr_complexity_limit) {
4872 Power = Opts.lsr_complexity_limit;
4876 if (Power >= Opts.lsr_complexity_limit)
4885void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
4886 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
4889 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by eliminating formulae "
4890 "which use a superset of registers used by other "
4893 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4894 LSRUse &LU =
Uses[LUIdx];
4896 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
4897 Formula &
F = LU.Formulae[i];
4898 if (
F.BaseOffset.isNonZero() &&
F.BaseOffset.isScalable())
4904 I =
F.BaseRegs.begin(),
E =
F.BaseRegs.end();
I !=
E; ++
I) {
4910 Immediate::getFixed(NewF.BaseOffset.getFixedValue() +
4911 (
uint64_t)
C->getValue()->getSExtValue());
4912 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4913 (
I -
F.BaseRegs.begin()));
4914 if (LU.HasFormulaWithSameRegs(NewF)) {
4917 LU.DeleteFormula(
F);
4928 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4929 (
I -
F.BaseRegs.begin()));
4930 if (LU.HasFormulaWithSameRegs(NewF)) {
4933 LU.DeleteFormula(
F);
4944 LU.RecomputeRegs(LUIdx, RegUses);
4953void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
4954 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
4958 dbgs() <<
"The search space is too complex.\n"
4959 "Narrowing the search space by assuming that uses separated "
4960 "by a constant offset will use the same registers.\n");
4964 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4965 LSRUse &LU =
Uses[LUIdx];
4966 for (
const Formula &
F : LU.Formulae) {
4967 if (
F.BaseOffset.isZero() || (
F.Scale != 0 &&
F.Scale != 1))
4969 assert((LU.Kind == LSRUse::Address || LU.Kind == LSRUse::ICmpZero) &&
4970 "Only address and cmp uses expected to have nonzero BaseOffset");
4972 LSRUse *LUThatHas = FindUseWithSimilarFormula(
F, LU);
4976 if (!reconcileNewOffset(*LUThatHas,
F.BaseOffset,
false,
4977 LU.Kind, LU.AccessTy))
4982 LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
4983 LUThatHas->AllFixupsUnconditional &= LU.AllFixupsUnconditional;
4986 for (LSRFixup &
Fixup : LU.Fixups) {
4987 Fixup.Offset +=
F.BaseOffset;
4988 LUThatHas->pushFixup(
Fixup);
4993 Type *FixupType = LUThatHas->Fixups[0].OperandValToReplace->getType();
4994 for (LSRFixup &
Fixup : LUThatHas->Fixups)
4995 assert(
Fixup.OperandValToReplace->getType() == FixupType &&
4996 "Expected all fixups to have the same type");
5001 for (
size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
5002 Formula &
F = LUThatHas->Formulae[i];
5003 if (!
isLegalUse(
TTI, LUThatHas->MinOffset, LUThatHas->MaxOffset,
5004 LUThatHas->Kind, LUThatHas->AccessTy,
F)) {
5006 LUThatHas->DeleteFormula(
F);
5014 LUThatHas->RecomputeRegs(LUThatHas - &
Uses.front(), RegUses);
5017 DeleteUse(LU, LUIdx);
5030void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
5031 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5034 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by re-filtering out "
5035 "undesirable dedicated registers.\n");
5037 FilterOutUndesirableDedicatedRegisters();
5052void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
5053 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5057 dbgs() <<
"The search space is too complex.\n"
5058 "Narrowing the search space by choosing the best Formula "
5059 "from the Formulae with the same Scale and ScaledReg.\n");
5062 using BestFormulaeTy = DenseMap<std::pair<const SCEV *, int64_t>,
size_t>;
5064 BestFormulaeTy BestFormulae;
5066 bool ChangedFormulae =
false;
5068 DenseSet<const SCEV *> VisitedRegs;
5069 SmallPtrSet<const SCEV *, 16> Regs;
5071 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5072 LSRUse &LU =
Uses[LUIdx];
5077 auto IsBetterThan = [&](Formula &FA, Formula &FB) {
5082 size_t FARegNum = 0;
5083 for (
const SCEV *
Reg : FA.BaseRegs) {
5084 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5085 FARegNum += (NumUses - UsedByIndices.
count() + 1);
5087 size_t FBRegNum = 0;
5088 for (
const SCEV *
Reg : FB.BaseRegs) {
5089 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5090 FBRegNum += (NumUses - UsedByIndices.
count() + 1);
5092 if (FARegNum != FBRegNum)
5093 return FARegNum < FBRegNum;
5097 Cost CostFA(Opts, L, SE,
TTI, AMK);
5098 Cost CostFB(Opts, L, SE,
TTI, AMK);
5100 CostFA.RateFormula(FA, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5102 CostFB.RateFormula(FB, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5103 return CostFA.isLess(CostFB);
5107 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5109 Formula &
F = LU.Formulae[FIdx];
5112 auto P = BestFormulae.insert({{
F.ScaledReg,
F.Scale}, FIdx});
5116 Formula &Best = LU.Formulae[
P.first->second];
5117 if (IsBetterThan(
F, Best))
5121 " in favor of formula ";
5122 Best.print(
dbgs());
dbgs() <<
'\n');
5124 ChangedFormulae =
true;
5126 LU.DeleteFormula(
F);
5132 LU.RecomputeRegs(LUIdx, RegUses);
5135 BestFormulae.clear();
5140 "After filtering out undesirable candidates:\n";
5147void LSRInstance::NarrowSearchSpaceByFilterPostInc() {
5150 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5154 "Narrowing the search space by choosing the lowest "
5155 "register Formula for PostInc Uses.\n");
5157 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5158 LSRUse &LU =
Uses[LUIdx];
5160 if (LU.Kind != LSRUse::Address)
5166 size_t MinRegs = std::numeric_limits<size_t>::max();
5167 for (
const Formula &
F : LU.Formulae)
5168 MinRegs = std::min(
F.getNumRegs(), MinRegs);
5171 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5173 Formula &
F = LU.Formulae[FIdx];
5174 if (
F.getNumRegs() > MinRegs) {
5177 LU.DeleteFormula(
F);
5184 LU.RecomputeRegs(LUIdx, RegUses);
5186 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5193void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
5194 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5198 dbgs() <<
"The search space is too complex.\n"
5199 "Narrowing the search space by merging uses with fixups "
5200 "entirely outside the loop with uses inside the loop.\n");
5202 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5203 LSRUse &LU =
Uses[LUIdx];
5206 if (!LU.AllFixupsOutsideLoop || LU.Formulae.empty() ||
5207 LU.Kind == LSRUse::ICmpZero)
5214 LSRUse *LUToMergeWith =
nullptr;
5215 const Formula &ThisF = LU.Formulae[0];
5216 for (LSRUse &OtherLU :
Uses) {
5218 if (OtherLU.AllFixupsOutsideLoop)
5222 if (OtherLU.Kind == LSRUse::ICmpZero)
5225 if (OtherLU.Formulae.empty())
5228 if (
any_of(OtherLU.Formulae, [&](
const Formula &
F) {
5229 return !isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, OtherLU.Kind,
5230 OtherLU.AccessTy, F);
5237 const Formula &OtherF = OtherLU.Formulae[0];
5238 if (ThisF.BaseRegs == OtherF.BaseRegs &&
5239 ThisF.ScaledReg == OtherF.ScaledReg &&
5240 ThisF.BaseGV == OtherF.BaseGV && ThisF.Scale == OtherF.Scale &&
5241 ThisF.UnfoldedOffset == OtherF.UnfoldedOffset &&
5242 ThisF.BaseOffset == OtherF.BaseOffset) {
5243 LUToMergeWith = &OtherLU;
5254 for (LSRFixup &
Fixup : LU.Fixups) {
5255 LUToMergeWith->pushFixup(
Fixup);
5259 DeleteUse(LU, LUIdx);
5309void LSRInstance::NarrowSearchSpaceByDeletingCostlyFormulas() {
5310 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5318 SmallPtrSet<const SCEV *, 4> UniqRegs;
5322 DenseMap <const SCEV *, float> RegNumMap;
5323 for (
const SCEV *
Reg : RegUses) {
5327 for (
const LSRUse &LU :
Uses) {
5328 if (!LU.Regs.count(
Reg))
5330 float P = LU.getNotSelectedProbability(
Reg);
5336 RegNumMap.
insert(std::make_pair(
Reg, PNotSel));
5340 dbgs() <<
"Narrowing the search space by deleting costly formulas\n");
5343 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5344 LSRUse &LU =
Uses[LUIdx];
5346 if (LU.Formulae.size() < 2)
5351 float FMinRegNum = LU.Formulae[0].getNumRegs();
5352 float FMinARegNum = LU.Formulae[0].getNumRegs();
5354 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5355 Formula &
F = LU.Formulae[i];
5358 for (
const SCEV *BaseReg :
F.BaseRegs) {
5359 if (UniqRegs.
count(BaseReg))
5361 FRegNum += RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5364 RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5366 if (
const SCEV *ScaledReg =
F.ScaledReg) {
5367 if (!UniqRegs.
count(ScaledReg)) {
5369 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5372 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5375 if (FMinRegNum > FRegNum ||
5376 (FMinRegNum == FRegNum && FMinARegNum > FARegNum)) {
5377 FMinRegNum = FRegNum;
5378 FMinARegNum = FARegNum;
5383 dbgs() <<
" with min reg num " << FMinRegNum <<
'\n');
5385 std::swap(LU.Formulae[MinIdx], LU.Formulae[0]);
5386 while (LU.Formulae.size() != 1) {
5389 LU.Formulae.pop_back();
5391 LU.RecomputeRegs(LUIdx, RegUses);
5392 assert(LU.Formulae.size() == 1 &&
"Should be exactly 1 min regs formula");
5393 Formula &
F = LU.Formulae[0];
5409 MemAccessTy AccessType) {
5419 return TTI.isLegalAddressingMode(
5420 AccessType.MemTy,
nullptr,
5421 Diff->getSExtValue(),
5422 true, 0, AccessType.AddrSpace) &&
5423 !
TTI.isLegalAddressingMode(
5424 AccessType.MemTy,
nullptr,
5425 -Diff->getSExtValue(),
5426 true, 0, AccessType.AddrSpace);
5432void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
5435 SmallPtrSet<const SCEV *, 4> Taken;
5436 while (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5443 const SCEV *Best =
nullptr;
5444 unsigned BestNum = 0;
5445 for (
const SCEV *
Reg : RegUses) {
5450 BestNum = RegUses.getUsedByIndices(
Reg).count();
5452 unsigned Count = RegUses.getUsedByIndices(
Reg).count();
5453 if (
Count > BestNum) {
5461 if (
Count == BestNum) {
5462 int LUIdx = RegUses.getUsedByIndices(
Reg).find_first();
5463 if (LUIdx >= 0 &&
Uses[LUIdx].Kind == LSRUse::Address &&
5465 Uses[LUIdx].AccessTy)) {
5472 assert(Best &&
"Failed to find best LSRUse candidate");
5474 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by assuming " << *Best
5475 <<
" will yield profitable reuse.\n");
5480 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5481 LSRUse &LU =
Uses[LUIdx];
5482 if (!LU.Regs.count(Best))
continue;
5485 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5486 Formula &
F = LU.Formulae[i];
5487 if (!
F.referencesReg(Best)) {
5489 LU.DeleteFormula(
F);
5493 assert(e != 0 &&
"Use has no formulae left! Is Regs inconsistent?");
5499 LU.RecomputeRegs(LUIdx, RegUses);
5510void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
5511 NarrowSearchSpaceByDetectingSupersets();
5512 NarrowSearchSpaceByCollapsingUnrolledCode();
5513 NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
5514 if (Opts.lsr_filter_same_scaled_reg)
5515 NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
5516 NarrowSearchSpaceByFilterPostInc();
5517 NarrowSearchSpaceByMergingUsesOutsideLoop();
5518 if (Opts.lsr_exp_narrow)
5519 NarrowSearchSpaceByDeletingCostlyFormulas();
5521 NarrowSearchSpaceByPickingWinnerRegs();
5525void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
5527 SmallVectorImpl<const Formula *> &Workspace,
5528 const Cost &CurCost,
5529 const SmallPtrSet<const SCEV *, 16> &CurRegs,
5530 DenseSet<const SCEV *> &VisitedRegs)
const {
5541 const LSRUse &LU =
Uses[Workspace.
size()];
5547 SmallSetVector<const SCEV *, 4> ReqRegs;
5548 for (
const SCEV *S : CurRegs)
5549 if (LU.Regs.count(S))
5552 SmallPtrSet<const SCEV *, 16> NewRegs;
5553 Cost NewCost(Opts, L, SE,
TTI, AMK);
5554 for (
const Formula &
F : LU.Formulae) {
5562 int NumReqRegsToFind = std::min(
F.getNumRegs(), ReqRegs.
size());
5563 for (
const SCEV *
Reg : ReqRegs) {
5564 if ((
F.ScaledReg &&
F.ScaledReg ==
Reg) ||
5567 if (NumReqRegsToFind == 0)
5571 if (NumReqRegsToFind != 0) {
5582 NewCost.RateFormula(
F, NewRegs, VisitedRegs, LU, HardwareLoopProfitable);
5583 if (NewCost.isLess(SolutionCost)) {
5585 if (Workspace.
size() !=
Uses.size()) {
5586 SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
5587 NewRegs, VisitedRegs);
5588 if (
F.getNumRegs() == 1 && Workspace.
size() == 1)
5589 VisitedRegs.
insert(
F.ScaledReg ?
F.ScaledReg :
F.BaseRegs[0]);
5592 dbgs() <<
".\nRegs:\n";
5593 for (
const SCEV *S : NewRegs)
dbgs()
5594 <<
"- " << *S <<
"\n";
5597 SolutionCost = NewCost;
5598 Solution = Workspace;
5607void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution)
const {
5609 Cost SolutionCost(Opts, L, SE,
TTI, AMK);
5610 SolutionCost.Lose();
5611 Cost CurCost(Opts, L, SE,
TTI, AMK);
5612 SmallPtrSet<const SCEV *, 16> CurRegs;
5613 DenseSet<const SCEV *> VisitedRegs;
5617 SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
5618 CurRegs, VisitedRegs);
5619 if (Solution.
empty()) {
5626 "The chosen solution requires ";
5627 SolutionCost.print(
dbgs());
dbgs() <<
":\n";
5628 for (
size_t i = 0, e =
Uses.size(); i != e; ++i) {
5633 Solution[i]->print(
dbgs());
5639 const bool EnableDropUnprofitableSolution =
valueOr(
5642 if (BaselineCost.isLess(SolutionCost)) {
5643 if (!EnableDropUnprofitableSolution)
5645 dbgs() <<
"Baseline is more profitable than chosen solution, "
5646 "add option 'lsr-drop-solution' to drop LSR solution.\n");
5649 "solution, dropping LSR solution.\n";);
5660 const SmallVectorImpl<Instruction *> &Inputs)
5664 bool AllDominate =
true;
5671 for (Instruction *Inst : Inputs) {
5672 if (Inst == Tentative || !DT.
dominates(Inst, Tentative)) {
5673 AllDominate =
false;
5678 if (Tentative->
getParent() == Inst->getParent() &&
5679 (!BetterPos || !DT.
dominates(Inst, BetterPos)))
5689 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
5690 unsigned IPLoopDepth = IPLoop ? IPLoop->
getLoopDepth() : 0;
5694 if (!Rung)
return IP;
5695 Rung = Rung->getIDom();
5696 if (!Rung)
return IP;
5697 IDom = Rung->getBlock();
5700 const Loop *IDomLoop = LI.getLoopFor(IDom);
5701 unsigned IDomDepth = IDomLoop ? IDomLoop->
getLoopDepth() : 0;
5702 if (IDomDepth <= IPLoopDepth &&
5703 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
5720 SmallVector<Instruction *, 4> Inputs;
5723 if (LU.Kind == LSRUse::ICmpZero)
5724 if (Instruction *
I =
5727 if (LF.PostIncLoops.
count(L)) {
5728 if (LF.isUseFullyOutsideLoop(L))
5729 Inputs.
push_back(
L->getLoopLatch()->getTerminator());
5735 for (
const Loop *PIL : LF.PostIncLoops) {
5736 if (PIL == L)
continue;
5741 if (!ExitingBlocks.
empty()) {
5743 for (
unsigned i = 1, e = ExitingBlocks.
size(); i != e; ++i)
5750 "Insertion point must be a normal instruction");
5760 while (IP->isEHPad()) ++IP;
5765 while (
Rewriter.isInsertedInstruction(&*IP) && IP != LowestIP)
5773Value *LSRInstance::Expand(
const LSRUse &LU,
const LSRFixup &LF,
5775 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const {
5776 if (LU.RigidFormula)
5777 return LF.OperandValToReplace;
5781 IP = AdjustInsertPositionForExpand(IP, LF, LU);
5786 Rewriter.setPostInc(LF.PostIncLoops);
5791 Type *Ty =
F.getType();
5804 if (LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy()) {
5813 for (
const SCEV *
Reg :
F.BaseRegs) {
5814 assert(!
Reg->isZero() &&
"Zero allocated in a base register!");
5822 Value *ICmpScaledV =
nullptr;
5824 const SCEV *ScaledS =
F.ScaledReg;
5830 if (LU.Kind == LSRUse::ICmpZero) {
5840 "The only scale supported by ICmpZero uses is -1!");
5841 ICmpScaledV =
Rewriter.expandCodeFor(ScaledS,
nullptr);
5849 if (!
Ops.empty() && LU.Kind == LSRUse::Address &&
5859 Ops.push_back(ScaledS);
5885 assert(
F.BaseOffset.isCompatibleImmediate(LF.Offset) &&
5886 "Expanding mismatched offsets\n");
5888 Immediate
Offset =
F.BaseOffset.addUnsigned(LF.Offset);
5889 if (
Offset.isNonZero()) {
5890 if (LU.Kind == LSRUse::ICmpZero) {
5906 Ops.push_back(
Offset.getUnknownSCEV(SE, IntTy));
5911 Immediate UnfoldedOffset =
F.UnfoldedOffset;
5912 if (UnfoldedOffset.isNonZero()) {
5914 Ops.push_back(UnfoldedOffset.getUnknownSCEV(SE, IntTy));
5928 if (LU.Kind == LSRUse::ICmpZero) {
5932 assert(!
F.BaseGV &&
"ICmp does not support folding a global value and "
5933 "a scale at the same time!");
5934 if (
F.Scale == -1) {
5935 if (ICmpScaledV->
getType() != OpTy) {
5945 assert((
F.Scale == 0 ||
F.Scale == 1) &&
5946 "ICmp does not support folding a global value and "
5947 "a scale at the same time!");
5953 if (
C->getType() != OpTy) {
5957 assert(
C &&
"Cast of ConstantInt should have folded");
5970void LSRInstance::RewriteForPHI(PHINode *PN,
const LSRUse &LU,
5971 const LSRFixup &LF,
const Formula &
F,
5972 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
5973 DenseMap<BasicBlock *, Value *>
Inserted;
5977 bool needUpdateFixups =
false;
5988 Loop *PNLoop = LI.getLoopFor(Parent);
5989 if (!PNLoop || Parent != PNLoop->
getHeader()) {
5993 CriticalEdgeSplittingOptions SplitOptions(&DT, &LI, MSSAU);
5995 SplitOptions.setMergeIdenticalEdges().setKeepOneInputPHIs();
5996 if (ShouldPreserveLCSSA)
5997 SplitOptions = SplitOptions.setPreserveLCSSA();
6001 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
6012 if (
L->contains(BB) && !
L->contains(PN))
6020 needUpdateFixups =
true;
6025 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> Pair =
6038 LF.OperandValToReplace->
getType(),
"tmp",
6045 if (
L->contains(
I) && !
L->contains(BB))
6046 InsertedNonLCSSAInsts.insert(
I);
6049 Pair.first->second = FullV;
6056 if (needUpdateFixups) {
6057 for (LSRUse &LU :
Uses)
6058 for (LSRFixup &
Fixup : LU.Fixups)
6062 if (
Fixup.UserInst == PN) {
6065 bool foundInOriginalPHI =
false;
6067 if (val ==
Fixup.OperandValToReplace) {
6068 foundInOriginalPHI =
true;
6073 if (foundInOriginalPHI)
6084 if (val ==
Fixup.OperandValToReplace)
6085 Fixup.UserInst = NewPN;
6095void LSRInstance::Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
6097 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6101 RewriteForPHI(PN, LU, LF,
F, DeadInsts);
6109 if (FullV->
getType() != OpTy &&
6110 !(LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy())) {
6122 if (LU.Kind == LSRUse::ICmpZero)
6138 const LSRFixup &
Fixup,
const LSRUse &LU,
6142 if (LU.Kind != LSRUse::Address)
6143 return IVIncInsertPos;
6147 Type *Ty =
I->getType();
6150 return IVIncInsertPos;
6157 return IVIncInsertPos;
6164void LSRInstance::ImplementSolution(
6165 const SmallVectorImpl<const Formula *> &Solution) {
6171 for (
const IVChain &Chain : IVChainVec) {
6177 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx)
6178 for (
const LSRFixup &
Fixup :
Uses[LUIdx].Fixups) {
6181 Rewriter.setIVIncInsertPos(L, InsertPos);
6182 Rewrite(
Uses[LUIdx],
Fixup, *Solution[LUIdx], DeadInsts);
6186 auto InsertedInsts = InsertedNonLCSSAInsts.takeVector();
6189 for (
const IVChain &Chain : IVChainVec) {
6190 GenerateIVChain(Chain, DeadInsts);
6194 for (
const WeakVH &
IV :
Rewriter.getInsertedIVs())
6212 for (PHINode &PN :
L->getHeader()->phis()) {
6213 BinaryOperator *BO =
nullptr;
6219 case Instruction::Sub:
6224 case Instruction::Add:
6241 [&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
6250LSRInstance::LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
6251 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
6252 const TargetTransformInfo &
TTI, AssumptionCache &AC,
6253 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
6255 : Opts(Opts), IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI),
TTI(
TTI),
6256 L(
L), MSSAU(MSSAU), AMK(Opts.lsr_preferred_addressing_mode.value_or(
6257 TTI.getPreferredAddressingMode(
L, &SE))),
6258 Rewriter(SE,
"lsr", PreserveLCSSA), ShouldPreserveLCSSA(PreserveLCSSA),
6259 BaselineCost(Opts,
L, SE,
TTI, AMK) {
6261 if (!
L->isLoopSimplifyForm())
6269 unsigned NumUsers = 0;
6273 LLVM_DEBUG(
dbgs() <<
"LSR skipping loop, too many IV Users in " << U
6281 auto FirstNonPHI = PN->
getParent()->getFirstNonPHIIt();
6291 L->getHeader()->printAsOperand(
dbgs(),
false);
6297 HardwareLoopProfitable =
6298 TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo);
6302#if LLVM_ENABLE_ABI_BREAKING_CHECKS
6305 Rewriter.disableCanonicalMode();
6306 Rewriter.enableLSRMode();
6310 OptimizeLoopTermCond();
6313 if (IU.empty())
return;
6316 if (!
L->isInnermost()) {
6329 CollectInterestingTypesAndFactors();
6330 CollectFixupsAndInitialFormulae();
6331 CollectLoopInvariantFixupsAndFormulae();
6337 print_uses(
dbgs()));
6339 BaselineCost.print(
dbgs());
dbgs() <<
"\n");
6343 GenerateAllReuseFormulae();
6345 FilterOutUndesirableDedicatedRegisters();
6346 NarrowSearchSpaceUsingHeuristics();
6356 if (Solution.
empty())
6361 for (
const LSRUse &LU :
Uses) {
6362 for (
const Formula &
F : LU.Formulae)
6364 F) &&
"Illegal formula generated!");
6369 ImplementSolution(Solution);
6372#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
6373void LSRInstance::print_factors_and_types(
raw_ostream &OS)
const {
6374 if (Factors.empty() &&
Types.empty())
return;
6376 OS <<
"LSR has identified the following interesting factors and types: ";
6379 for (int64_t Factor : Factors)
6380 OS <<
LS <<
'*' << Factor;
6382 for (
Type *Ty : Types)
6383 OS <<
LS <<
'(' << *Ty <<
')';
6387void LSRInstance::print_fixups(raw_ostream &OS)
const {
6388 OS <<
"LSR is examining the following fixup sites:\n";
6389 for (
const LSRUse &LU :
Uses)
6390 for (
const LSRFixup &LF : LU.Fixups) {
6397void LSRInstance::print_uses(raw_ostream &OS)
const {
6398 OS <<
"LSR is examining the following uses:\n";
6399 for (
const LSRUse &LU :
Uses) {
6403 for (
const Formula &
F : LU.Formulae) {
6411void LSRInstance::print(raw_ostream &OS)
const {
6412 print_factors_and_types(OS);
6424class LoopStrengthReduce :
public LoopPass {
6428 LoopStrengthReduce();
6431 bool runOnLoop(
Loop *L, LPPassManager &LPM)
override;
6432 void getAnalysisUsage(AnalysisUsage &AU)
const override;
6437LoopStrengthReduce::LoopStrengthReduce() : LoopPass(
ID) {
6441void LoopStrengthReduce::getAnalysisUsage(
AnalysisUsage &AU)
const {
6468ToDwarfOpIter(SmallVectorImpl<uint64_t> &Expr) {
6469 llvm::DIExpression::expr_op_iterator Begin =
6470 llvm::DIExpression::expr_op_iterator(Expr.
begin());
6471 llvm::DIExpression::expr_op_iterator
End =
6472 llvm::DIExpression::expr_op_iterator(Expr.
end());
6473 return {Begin,
End};
6476struct SCEVDbgValueBuilder {
6477 SCEVDbgValueBuilder() =
default;
6478 SCEVDbgValueBuilder(
const SCEVDbgValueBuilder &
Base) { clone(
Base); }
6480 void clone(
const SCEVDbgValueBuilder &
Base) {
6481 LocationOps =
Base.LocationOps;
6486 LocationOps.
clear();
6493 SmallVector<Value *, 2> LocationOps;
6503 unsigned ArgIndex = 0;
6504 if (It != LocationOps.
end()) {
6505 ArgIndex = std::distance(LocationOps.
begin(), It);
6507 ArgIndex = LocationOps.
size();
6513 void pushValue(
const SCEVUnknown *U) {
6518 bool pushConst(
const SCEVConstant *
C) {
6519 if (
C->getAPInt().getSignificantBits() > 64)
6521 Expr.
push_back(llvm::dwarf::DW_OP_consts);
6522 Expr.
push_back(
C->getAPInt().getSExtValue());
6529 return ToDwarfOpIter(Expr);
6534 bool pushArithmeticExpr(
const llvm::SCEVCommutativeExpr *CommExpr,
6537 "Expected arithmetic SCEV type");
6539 unsigned EmitOperator = 0;
6540 for (
const auto &
Op : CommExpr->
operands()) {
6543 if (EmitOperator >= 1)
6544 pushOperator(DwarfOp);
6551 bool pushCast(
const llvm::SCEVCastExpr *
C,
bool IsSigned) {
6552 const llvm::SCEV *Inner =
C->getOperand(0);
6553 const llvm::Type *
Type =
C->getType();
6555 bool Success = pushSCEV(Inner);
6557 IsSigned ? llvm::dwarf::DW_ATE_signed
6558 : llvm::dwarf::DW_ATE_unsigned};
6559 for (
const auto &
Op : CastOps)
6565 bool pushSCEV(
const llvm::SCEV *S) {
6568 Success &= pushConst(StartInt);
6573 pushLocation(
U->getValue());
6576 Success &= pushArithmeticExpr(MulRec, llvm::dwarf::DW_OP_mul);
6579 Success &= pushSCEV(UDiv->getLHS());
6580 Success &= pushSCEV(UDiv->getRHS());
6581 pushOperator(llvm::dwarf::DW_OP_div);
6587 "Unexpected cast type in SCEV.");
6591 Success &= pushArithmeticExpr(AddExpr, llvm::dwarf::DW_OP_plus);
6606 bool isIdentityFunction(
uint64_t Op,
const SCEV *S) {
6608 if (
C->getAPInt().getSignificantBits() > 64)
6610 int64_t
I =
C->getAPInt().getSExtValue();
6612 case llvm::dwarf::DW_OP_plus:
6613 case llvm::dwarf::DW_OP_minus:
6615 case llvm::dwarf::DW_OP_mul:
6616 case llvm::dwarf::DW_OP_div:
6629 bool SCEVToValueExpr(
const llvm::SCEVAddRecExpr &SAR, ScalarEvolution &SE) {
6635 if (!isIdentityFunction(llvm::dwarf::DW_OP_mul, Stride)) {
6636 if (!pushSCEV(Stride))
6638 pushOperator(llvm::dwarf::DW_OP_mul);
6640 if (!isIdentityFunction(llvm::dwarf::DW_OP_plus, Start)) {
6641 if (!pushSCEV(Start))
6643 pushOperator(llvm::dwarf::DW_OP_plus);
6649 void createOffsetExpr(int64_t
Offset,
Value *OffsetValue) {
6650 pushLocation(OffsetValue);
6653 dbgs() <<
"scev-salvage: Generated IV offset expression. Offset: "
6654 << std::to_string(
Offset) <<
"\n");
6660 bool createIterCountExpr(
const SCEV *S,
6661 const SCEVDbgValueBuilder &IterationCount,
6662 ScalarEvolution &SE) {
6671 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Location to salvage SCEV: " << *S
6675 if (!Rec->isAffine())
6683 clone(IterationCount);
6684 if (!SCEVToValueExpr(*Rec, SE))
6695 bool SCEVToIterCountExpr(
const llvm::SCEVAddRecExpr &SAR,
6696 ScalarEvolution &SE) {
6702 if (!isIdentityFunction(llvm::dwarf::DW_OP_minus, Start)) {
6703 if (!pushSCEV(Start))
6705 pushOperator(llvm::dwarf::DW_OP_minus);
6707 if (!isIdentityFunction(llvm::dwarf::DW_OP_div, Stride)) {
6708 if (!pushSCEV(Stride))
6710 pushOperator(llvm::dwarf::DW_OP_div);
6718 void appendToVectors(SmallVectorImpl<uint64_t> &DestExpr,
6719 SmallVectorImpl<Value *> &DestLocations) {
6721 "Expected the locations vector to contain the IV");
6726 "Expected the location ops to contain the IV.");
6730 for (
const auto &
Op : LocationOps) {
6731 auto It =
find(DestLocations,
Op);
6732 if (It != DestLocations.
end()) {
6734 DestIndexMap.
push_back(std::distance(DestLocations.
begin(), It));
6742 for (
const auto &
Op : expr_ops()) {
6745 Op.appendToVector(DestExpr);
6752 uint64_t NewIndex = DestIndexMap[Arg.getIndex()];
6760struct DVIRecoveryRec {
6761 DVIRecoveryRec(DbgVariableRecord *DVR)
6762 : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(
false) {}
6764 DbgVariableRecord *DbgRef;
6766 bool HadLocationArgList;
6772 for (
auto &RE : RecoveryExprs)
6774 RecoveryExprs.clear();
6777 ~DVIRecoveryRec() { clear(); }
6785 auto expr_ops = ToDwarfOpIter(Expr);
6787 for (
auto Op : expr_ops)
6796template <
typename T>
6800 "contain any DW_OP_llvm_arg operands.");
6806template <
typename T>
6811 "Expected expression that references DIArglist locations using "
6812 "DW_OP_llvm_arg operands.");
6814 for (
Value *V : Locations)
6831 if (NumLLVMArgs == 0) {
6838 "Lone LLVM_arg in a DIExpression should refer to location-op 0.");
6868 LLVM_DEBUG(
dbgs() <<
"scev-salvage: restore dbg.value to pre-LSR state\n"
6869 <<
"scev-salvage: post-LSR: " << *DbgVal <<
'\n');
6870 assert(DVIRec.Expr &&
"Expected an expression");
6875 if (!DVIRec.HadLocationArgList) {
6876 assert(DVIRec.LocationOps.size() == 1 &&
6877 "Unexpected number of location ops.");
6881 Value *CachedValue =
6886 for (
WeakVH VH : DVIRec.LocationOps) {
6894 LLVM_DEBUG(
dbgs() <<
"scev-salvage: pre-LSR: " << *DbgVal <<
'\n');
6899 const SCEV *SCEVInductionVar,
6900 SCEVDbgValueBuilder IterCountExpr) {
6914 LocationOpIndexMap.
assign(DVIRec.LocationOps.size(), -1);
6916 NewLocationOps.
push_back(LSRInductionVar);
6918 for (
unsigned i = 0; i < DVIRec.LocationOps.size(); i++) {
6919 WeakVH VH = DVIRec.LocationOps[i];
6925 LocationOpIndexMap[i] = NewLocationOps.
size() - 1;
6927 <<
" now at index " << LocationOpIndexMap[i] <<
"\n");
6935 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV for location at index: " << i
6936 <<
" refers to a location that is now undef or erased. "
6937 "Salvage abandoned.\n");
6941 LLVM_DEBUG(
dbgs() <<
"scev-salvage: salvaging location at index " << i
6942 <<
" with SCEV: " << *DVIRec.SCEVs[i] <<
"\n");
6944 DVIRec.RecoveryExprs[i] = std::make_unique<SCEVDbgValueBuilder>();
6945 SCEVDbgValueBuilder *SalvageExpr = DVIRec.RecoveryExprs[i].get();
6949 if (std::optional<APInt>
Offset =
6951 if (
Offset->getSignificantBits() <= 64)
6952 SalvageExpr->createOffsetExpr(
Offset->getSExtValue(), LSRInductionVar);
6955 }
else if (!SalvageExpr->createIterCountExpr(DVIRec.SCEVs[i], IterCountExpr,
6964 assert(DVIRec.RecoveryExprs.size() == 1 &&
6965 "Expected only a single recovery expression for an empty "
6967 assert(DVIRec.RecoveryExprs[0] &&
6968 "Expected a SCEVDbgSalvageBuilder for location 0");
6969 SCEVDbgValueBuilder *
B = DVIRec.RecoveryExprs[0].get();
6970 B->appendToVectors(
NewExpr, NewLocationOps);
6972 for (
const auto &
Op : DVIRec.Expr->
expr_ops()) {
6980 uint64_t LocationArgIndex = Arg.getIndex();
6981 SCEVDbgValueBuilder *DbgBuilder =
6982 DVIRec.RecoveryExprs[LocationArgIndex].get();
6988 assert(LocationOpIndexMap[LocationArgIndex] != -1 &&
6989 "Expected a positive index for the location-op position.");
6990 NewExpr.push_back(LocationOpIndexMap[LocationArgIndex]);
6994 DbgBuilder->appendToVectors(
NewExpr, NewLocationOps);
6998 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Updated DVI: " << *DVIRec.DbgRef <<
"\n");
7006 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &DVIToUpdate) {
7007 if (DVIToUpdate.empty())
7011 assert(SCEVInductionVar &&
7012 "Anticipated a SCEV for the post-LSR induction variable");
7016 if (!IVAddRec->isAffine())
7024 SCEVDbgValueBuilder IterCountExpr;
7025 IterCountExpr.pushLocation(LSRInductionVar);
7026 if (!IterCountExpr.SCEVToIterCountExpr(*IVAddRec, SE))
7029 LLVM_DEBUG(
dbgs() <<
"scev-salvage: IV SCEV: " << *SCEVInductionVar
7032 for (
auto &DVIRec : DVIToUpdate) {
7033 SalvageDVI(L, SE, LSRInductionVar, *DVIRec, SCEVInductionVar,
7044 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &SalvageableDVISCEVs) {
7045 for (
const auto &
B : L->getBlocks()) {
7046 for (
auto &
I : *
B) {
7048 if (!DbgVal.isDbgValue() && !DbgVal.isDbgAssign())
7053 if (DbgVal.isKillLocation())
7058 const auto &HasTranslatableLocationOps =
7060 for (
const auto LocOp : DbgValToTranslate.location_ops()) {
7074 if (!HasTranslatableLocationOps(DbgVal))
7077 std::unique_ptr<DVIRecoveryRec> NewRec =
7078 std::make_unique<DVIRecoveryRec>(&DbgVal);
7082 NewRec->RecoveryExprs.resize(DbgVal.getNumVariableLocationOps());
7083 for (
const auto LocOp : DbgVal.location_ops()) {
7084 NewRec->SCEVs.push_back(SE.
getSCEV(LocOp));
7085 NewRec->LocationOps.push_back(LocOp);
7086 NewRec->HadLocationArgList = DbgVal.hasArgList();
7088 SalvageableDVISCEVs.push_back(std::move(NewRec));
7098 const LSRInstance &LSR) {
7100 auto IsSuitableIV = [&](
PHINode *
P) {
7111 for (
const WeakVH &
IV : LSR.getScalarEvolutionIVs()) {
7118 if (IsSuitableIV(
P))
7122 for (
PHINode &
P : L.getHeader()->phis()) {
7123 if (IsSuitableIV(&
P))
7134 const ScalarOptions &Opts = ScalarOptions::Global;
7142 std::unique_ptr<MemorySSAUpdater> MSSAU;
7144 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
7147 const LSRInstance &Reducer = LSRInstance(Opts, L, IU, SE, DT, LI,
TTI, AC,
7148 TLI, MSSAU.get(), PreserveLCSSA);
7149 Changed |= Reducer.getChanged();
7153 if (Opts.enable_lsr_phielim && L->isLoopSimplifyForm()) {
7156#if LLVM_ENABLE_ABI_BREAKING_CHECKS
7159 unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &
TTI);
7173 if (L->isRecursivelyLCSSAForm(DT, LI) && L->getExitBlock()) {
7187 if (SalvageableDVIRecords.
empty())
7193 for (
const auto &L : LI) {
7197 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV salvaging not possible. An IV "
7198 "could not be identified.\n");
7202 for (
auto &Rec : SalvageableDVIRecords)
7204 SalvageableDVIRecords.
clear();
7208bool LoopStrengthReduce::runOnLoop(
Loop *L, LPPassManager & ) {
7212 auto &IU = getAnalysis<IVUsersWrapperPass>().getIU();
7213 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
7214 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7215 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
7216 const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
7217 *
L->getHeader()->getParent());
7218 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
7219 *
L->getHeader()->getParent());
7220 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
7221 *
L->getHeader()->getParent());
7222 auto *MSSAAnalysis = getAnalysisIfAvailable<MemorySSAWrapperPass>();
7225 MSSA = &MSSAAnalysis->getMSSA();
7244char LoopStrengthReduce::ID = 0;
7247 "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 stressIVChain(const ScalarOptions &Opts)
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 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 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.
@ 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)
@ End
Run the machine verifier once, at the end of the pipeline.
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