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) {
786 if (
RA.isAllOnes()) {
787 if (
LHS->getType()->isPointerTy())
800 const APInt &LA =
C->getAPInt();
809 if ((IgnoreSignificantBits ||
isAddRecSExtable(AR, SE)) && AR->isAffine()) {
811 IgnoreSignificantBits);
812 if (!Step)
return nullptr;
814 IgnoreSignificantBits);
815 if (!Start)
return nullptr;
828 for (
const SCEV *S :
Add->operands()) {
830 if (!
Op)
return nullptr;
858 for (
const SCEV *S :
Mul->operands()) {
861 IgnoreSignificantBits)) {
882 bool PreferScalable) {
885 Immediate Result = Immediate::getZero();
894 C->getSignificantBits() <= 64) {
896 Result = Immediate::getFixed(
C->getSExtValue());
901 if (Opts.lsr_enable_vscale_immediates &&
902 (Result.isZero() || PreferScalable)) {
909 Result = Immediate::getScalable(
C->getSExtValue());
915 if (Result.isNonZero()) {
927 bool PreferScalable =
false) {
934 if (Result.isNonZero())
941 if (Result.isNonZero())
982 if (
SI->getPointerOperand() == OperandVal)
987 switch (
II->getIntrinsicID()) {
988 case Intrinsic::memset:
989 case Intrinsic::prefetch:
990 case Intrinsic::masked_load:
991 if (
II->getArgOperand(0) == OperandVal)
994 case Intrinsic::masked_store:
995 if (
II->getArgOperand(1) == OperandVal)
998 case Intrinsic::memmove:
999 case Intrinsic::memcpy:
1000 if (
II->getArgOperand(0) == OperandVal ||
1001 II->getArgOperand(1) == OperandVal)
1006 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo)) {
1007 if (IntrInfo.
PtrVal == OperandVal)
1013 if (RMW->getPointerOperand() == OperandVal)
1016 if (CmpX->getPointerOperand() == OperandVal)
1025 MemAccessTy AccessTy = MemAccessTy::getUnknown(Inst->
getContext());
1029 AccessTy.MemTy = Ty;
1033 AccessTy.AddrSpace =
SI->getPointerAddressSpace();
1035 AccessTy.AddrSpace = LI->getPointerAddressSpace();
1037 AccessTy.AddrSpace = RMW->getPointerAddressSpace();
1039 AccessTy.AddrSpace = CmpX->getPointerAddressSpace();
1041 switch (
II->getIntrinsicID()) {
1042 case Intrinsic::prefetch:
1043 case Intrinsic::memset:
1044 AccessTy.AddrSpace =
II->getArgOperand(0)->getType()->getPointerAddressSpace();
1045 AccessTy.MemTy = OperandVal->
getType();
1047 case Intrinsic::memmove:
1048 case Intrinsic::memcpy:
1050 AccessTy.MemTy = OperandVal->
getType();
1052 case Intrinsic::masked_load:
1053 AccessTy.AddrSpace =
1054 II->getArgOperand(0)->getType()->getPointerAddressSpace();
1056 case Intrinsic::masked_store:
1057 AccessTy.AddrSpace =
1058 II->getArgOperand(1)->getType()->getPointerAddressSpace();
1062 if (
TTI.getTgtMemIntrinsic(
II, IntrInfo) && IntrInfo.
PtrVal) {
1118 if (!Processed.
insert(S).second)
1122 for (
const SCEV *S :
Add->operands()) {
1129 const SCEV *Op0, *Op1;
1138 Value *UVal = U->getValue();
1142 if (UI && UI->
getOpcode() == Instruction::Mul &&
1175 const LSRUse &LU,
const Formula &
F);
1179 const LSRUse &LU,
const Formula &
F,
1186 const ScalarOptions *Opts =
nullptr;
1187 const Loop *
L =
nullptr;
1188 ScalarEvolution *SE =
nullptr;
1189 const TargetTransformInfo *
TTI =
nullptr;
1190 TargetTransformInfo::LSRCost
C;
1195 Cost(
const ScalarOptions &Opts,
const Loop *L, ScalarEvolution &SE,
1197 : Opts(&Opts),
L(
L), SE(&SE),
TTI(&
TTI), AMK(AMK) {
1215 return ((
C.Insns |
C.NumRegs |
C.AddRecCost |
C.NumIVMuls |
C.NumBaseAdds
1216 |
C.ImmCost |
C.SetupCost |
C.ScaleCost) != ~0u)
1217 || ((
C.Insns &
C.NumRegs &
C.AddRecCost &
C.NumIVMuls &
C.NumBaseAdds
1218 &
C.ImmCost &
C.SetupCost &
C.ScaleCost) == ~0
u);
1224 return C.NumRegs == ~0
u;
1227 void RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1228 const DenseSet<const SCEV *> &VisitedRegs,
const LSRUse &LU,
1229 bool HardwareLoopProfitable,
1230 SmallPtrSetImpl<const SCEV *> *LoserRegs =
nullptr);
1232 void print(raw_ostream &OS)
const;
1236 void RateRegister(
const Formula &
F,
const SCEV *
Reg,
1237 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1238 bool HardwareLoopProfitable);
1239 void RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1240 SmallPtrSetImpl<const SCEV *> &Regs,
1241 const LSRUse &LU,
bool HardwareLoopProfitable,
1242 SmallPtrSetImpl<const SCEV *> *LoserRegs);
1253 Value *OperandValToReplace =
nullptr;
1263 Immediate
Offset = Immediate::getZero();
1265 LSRFixup() =
default;
1267 bool isUseFullyOutsideLoop(
const Loop *L)
const;
1269 void print(raw_ostream &OS)
const;
1279 DenseSet<SmallVector<const SCEV *, 4>> Uniquifier;
1292 using SCEVUseKindPair = PointerIntPair<const SCEV *, 2, KindType>;
1295 MemAccessTy AccessTy;
1301 Immediate MinOffset = Immediate::getFixedMax();
1302 Immediate MaxOffset = Immediate::getFixedMin();
1306 bool AllFixupsOutsideLoop =
true;
1311 bool AllFixupsUnconditional =
true;
1318 bool RigidFormula =
false;
1326 SmallPtrSet<const SCEV *, 4> Regs;
1328 LSRUse(KindType K, MemAccessTy AT) :
Kind(
K), AccessTy(AT) {}
1330 LSRFixup &getNewFixup() {
1331 Fixups.push_back(LSRFixup());
1335 void pushFixup(LSRFixup &f) {
1337 if (Immediate::isKnownGT(
f.Offset, MaxOffset))
1338 MaxOffset =
f.Offset;
1339 if (Immediate::isKnownLT(
f.Offset, MinOffset))
1340 MinOffset =
f.Offset;
1343 bool HasFormulaWithSameRegs(
const Formula &
F)
const;
1344 float getNotSelectedProbability(
const SCEV *
Reg)
const;
1345 bool InsertFormula(
const Formula &
F,
const Loop &L);
1346 void DeleteFormula(Formula &
F);
1347 void RecomputeRegs(
size_t LUIdx, RegUseTracker &Reguses);
1349 void print(raw_ostream &OS)
const;
1356 LSRUse::KindType Kind, MemAccessTy AccessTy,
1357 GlobalValue *BaseGV, Immediate BaseOffset,
1358 bool HasBaseReg, int64_t Scale,
1359 Instruction *
Fixup =
nullptr);
1366 if (
TTI.getIntImmCost(
C->getAPInt(),
C->getType(),
1380 [&](
unsigned i,
const SCEV *
Reg) {
1381 return i + getSetupCost(Reg, Depth - 1, TTI);
1390void Cost::RateRegister(
const Formula &
F,
const SCEV *
Reg,
1391 SmallPtrSetImpl<const SCEV *> &Regs,
const LSRUse &LU,
1392 bool HardwareLoopProfitable) {
1397 if (AR->getLoop() != L) {
1404 if (!AR->getLoop()->contains(L)) {
1414 unsigned LoopCost = 1;
1423 F.BaseOffset.isFixed() &&
1424 *Step ==
F.BaseOffset.getFixedValue();
1429 if ((CanPreIndex || CanPostIndex) && LU.AllFixupsUnconditional)
1436 if (LU.Kind == LSRUse::ICmpZero &&
F.countsDownToZero() &&
1437 HardwareLoopProfitable)
1439 C.AddRecCost += LoopCost;
1443 const SCEV *StepReg = AR->getOperand(1);
1448 auto IsVScaleStep = [](
const SCEV *
Reg,
const TargetTransformInfo *
TTI) {
1454 if (!Regs.
count(StepReg) && !IsVScaleStep(StepReg,
TTI)) {
1455 RateRegister(
F, StepReg, Regs, LU, HardwareLoopProfitable);
1467 C.SetupCost = std::min<unsigned>(
C.SetupCost, 1 << 16);
1476void Cost::RatePrimaryRegister(
const Formula &
F,
const SCEV *
Reg,
1477 SmallPtrSetImpl<const SCEV *> &Regs,
1478 const LSRUse &LU,
bool HardwareLoopProfitable,
1479 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1480 if (LoserRegs && LoserRegs->
count(
Reg)) {
1485 RateRegister(
F,
Reg, Regs, LU, HardwareLoopProfitable);
1486 if (LoserRegs && isLoser())
1491void Cost::RateFormula(
const Formula &
F, SmallPtrSetImpl<const SCEV *> &Regs,
1492 const DenseSet<const SCEV *> &VisitedRegs,
1493 const LSRUse &LU,
bool HardwareLoopProfitable,
1494 SmallPtrSetImpl<const SCEV *> *LoserRegs) {
1497 assert(
F.isCanonical(*L) &&
"Cost is accurate only for canonical formula");
1499 unsigned PrevAddRecCost =
C.AddRecCost;
1500 unsigned PrevNumRegs =
C.NumRegs;
1501 unsigned PrevNumBaseAdds =
C.NumBaseAdds;
1502 if (
const SCEV *ScaledReg =
F.ScaledReg) {
1503 if (VisitedRegs.
count(ScaledReg)) {
1507 RatePrimaryRegister(
F, ScaledReg, Regs, LU, HardwareLoopProfitable,
1512 for (
const SCEV *BaseReg :
F.BaseRegs) {
1513 if (VisitedRegs.
count(BaseReg)) {
1517 RatePrimaryRegister(
F, BaseReg, Regs, LU, HardwareLoopProfitable,
1524 size_t NumBaseParts =
F.getNumRegs();
1525 if (NumBaseParts > 1)
1530 C.NumBaseAdds += (
F.UnfoldedOffset.isNonZero());
1536 for (
const LSRFixup &
Fixup : LU.Fixups) {
1537 if (
Fixup.Offset.isCompatibleImmediate(
F.BaseOffset)) {
1538 Immediate
Offset =
Fixup.Offset.addUnsigned(
F.BaseOffset);
1542 else if (
Offset.isNonZero())
1544 APInt(64,
Offset.getKnownMinValue(),
true).getSignificantBits();
1548 if (LU.Kind == LSRUse::Address &&
Offset.isNonZero() &&
1559 if (!
valueOr(Opts->lsr_insns_cost,
true)) {
1569 if (
C.NumRegs > TTIRegNum) {
1572 if (PrevNumRegs > TTIRegNum)
1573 C.Insns += (
C.NumRegs - PrevNumRegs);
1575 C.Insns += (
C.NumRegs - TTIRegNum);
1588 if (LU.Kind == LSRUse::ICmpZero && !
F.hasZeroEnd() &&
1592 C.Insns += (
C.AddRecCost - PrevAddRecCost);
1595 if (LU.Kind != LSRUse::ICmpZero)
1596 C.Insns +=
C.NumBaseAdds - PrevNumBaseAdds;
1602 C.Insns = std::numeric_limits<unsigned>::max();
1603 C.NumRegs = std::numeric_limits<unsigned>::max();
1604 C.AddRecCost = std::numeric_limits<unsigned>::max();
1605 C.NumIVMuls = std::numeric_limits<unsigned>::max();
1606 C.NumBaseAdds = std::numeric_limits<unsigned>::max();
1607 C.ImmCost = std::numeric_limits<unsigned>::max();
1608 C.SetupCost = std::numeric_limits<unsigned>::max();
1609 C.ScaleCost = std::numeric_limits<unsigned>::max();
1613bool Cost::isLess(
const Cost &
Other)
const {
1614 if (Opts->lsr_insns_cost == BoolOrDefault::True &&
C.Insns !=
Other.C.Insns)
1615 return C.Insns <
Other.C.Insns;
1619#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1621 if (
valueOr(Opts->lsr_insns_cost,
true))
1622 OS <<
C.Insns <<
" instruction" << (
C.Insns == 1 ?
" " :
"s ");
1623 OS <<
C.NumRegs <<
" reg" << (
C.NumRegs == 1 ?
"" :
"s");
1624 if (
C.AddRecCost != 0)
1625 OS <<
", with addrec cost " <<
C.AddRecCost;
1626 if (
C.NumIVMuls != 0)
1627 OS <<
", plus " <<
C.NumIVMuls <<
" IV mul"
1628 << (
C.NumIVMuls == 1 ?
"" :
"s");
1629 if (
C.NumBaseAdds != 0)
1630 OS <<
", plus " <<
C.NumBaseAdds <<
" base add"
1631 << (
C.NumBaseAdds == 1 ?
"" :
"s");
1632 if (
C.ScaleCost != 0)
1633 OS <<
", plus " <<
C.ScaleCost <<
" scale cost";
1635 OS <<
", plus " <<
C.ImmCost <<
" imm cost";
1636 if (
C.SetupCost != 0)
1637 OS <<
", plus " <<
C.SetupCost <<
" setup cost";
1646bool LSRFixup::isUseFullyOutsideLoop(
const Loop *L)
const {
1649 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1650 if (PN->getIncomingValue(i) == OperandValToReplace &&
1651 L->contains(PN->getIncomingBlock(i)))
1656 return !
L->contains(UserInst);
1659#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1660void LSRFixup::print(raw_ostream &OS)
const {
1665 Store->getOperand(0)->printAsOperand(OS,
false);
1671 OS <<
", OperandValToReplace=";
1674 for (
const Loop *PIL : PostIncLoops) {
1675 OS <<
", PostIncLoop=";
1676 PIL->getHeader()->printAsOperand(OS,
false);
1680 OS <<
", Offset=" <<
Offset;
1690bool LSRUse::HasFormulaWithSameRegs(
const Formula &
F)
const {
1692 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1699float LSRUse::getNotSelectedProbability(
const SCEV *
Reg)
const {
1701 for (
const Formula &
F : Formulae)
1702 if (
F.referencesReg(
Reg))
1704 return ((
float)(Formulae.size() - FNum)) / Formulae.size();
1709bool LSRUse::InsertFormula(
const Formula &
F,
const Loop &L) {
1710 assert(
F.isCanonical(L) &&
"Invalid canonical representation");
1712 if (!Formulae.empty() && RigidFormula)
1716 if (
F.ScaledReg)
Key.push_back(
F.ScaledReg);
1724 assert((!
F.ScaledReg || !
F.ScaledReg->isZero()) &&
1725 "Zero allocated in a scaled register!");
1727 for (
const SCEV *BaseReg :
F.BaseRegs)
1728 assert(!
BaseReg->isZero() &&
"Zero allocated in a base register!");
1732 Formulae.push_back(
F);
1743void LSRUse::DeleteFormula(Formula &
F) {
1744 if (&
F != &Formulae.back())
1746 Formulae.pop_back();
1750void LSRUse::RecomputeRegs(
size_t LUIdx, RegUseTracker &RegUses) {
1752 SmallPtrSet<const SCEV *, 4> OldRegs = std::move(Regs);
1754 for (
const Formula &
F : Formulae) {
1755 if (
F.ScaledReg) Regs.
insert(
F.ScaledReg);
1760 for (
const SCEV *S : OldRegs)
1762 RegUses.dropRegister(S, LUIdx);
1765#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1766void LSRUse::print(raw_ostream &OS)
const {
1767 OS <<
"LSR Use: Kind=";
1769 case Basic: OS <<
"Basic";
break;
1770 case Special: OS <<
"Special";
break;
1771 case ICmpZero: OS <<
"ICmpZero";
break;
1773 OS <<
"Address of ";
1777 OS << *AccessTy.MemTy;
1780 OS <<
" in addrspace(" << AccessTy.AddrSpace <<
')';
1783 OS <<
", Offsets={";
1784 bool NeedComma =
false;
1785 for (
const LSRFixup &
Fixup : Fixups) {
1786 if (NeedComma) OS <<
',';
1792 if (AllFixupsOutsideLoop)
1793 OS <<
", all-fixups-outside-loop";
1795 if (AllFixupsUnconditional)
1796 OS <<
", all-fixups-unconditional";
1805 LSRUse::KindType Kind, MemAccessTy AccessTy,
1807 bool HasBaseReg, int64_t Scale,
1810 case LSRUse::Address: {
1811 int64_t FixedOffset =
1812 BaseOffset.isScalable() ? 0 : BaseOffset.getFixedValue();
1813 int64_t ScalableOffset =
1814 BaseOffset.isScalable() ? BaseOffset.getKnownMinValue() : 0;
1815 return TTI.isLegalAddressingMode(AccessTy.MemTy, BaseGV, FixedOffset,
1816 HasBaseReg, Scale, AccessTy.AddrSpace,
1817 Fixup, ScalableOffset);
1819 case LSRUse::ICmpZero:
1826 if (Scale != 0 && HasBaseReg && BaseOffset.isNonZero())
1831 if (Scale != 0 && Scale != -1)
1836 if (BaseOffset.isNonZero()) {
1839 if (BaseOffset.isScalable())
1849 BaseOffset = BaseOffset.getFixed(-(
uint64_t)BaseOffset.getFixedValue());
1850 return TTI.isLegalICmpImmediate(BaseOffset.getFixedValue());
1858 return !BaseGV && Scale == 0 && BaseOffset.isZero();
1860 case LSRUse::Special:
1862 return !BaseGV && (Scale == 0 || Scale == -1) && BaseOffset.isZero();
1869 Immediate MinOffset, Immediate MaxOffset,
1870 LSRUse::KindType Kind, MemAccessTy AccessTy,
1872 bool HasBaseReg, int64_t Scale) {
1873 if (BaseOffset.isNonZero() &&
1874 (BaseOffset.isScalable() != MinOffset.isScalable() ||
1875 BaseOffset.isScalable() != MaxOffset.isScalable()))
1878 int64_t
Base = BaseOffset.getKnownMinValue();
1879 int64_t Min = MinOffset.getKnownMinValue();
1880 int64_t Max = MaxOffset.getKnownMinValue();
1883 MinOffset = Immediate::get((
uint64_t)
Base + Min, MinOffset.isScalable());
1886 MaxOffset = Immediate::get((
uint64_t)
Base + Max, MaxOffset.isScalable());
1889 HasBaseReg, Scale) &&
1895 Immediate MinOffset, Immediate MaxOffset,
1896 LSRUse::KindType Kind, MemAccessTy AccessTy,
1897 const Formula &
F,
const Loop &L) {
1905 assert((
F.isCanonical(L) ||
F.Scale != 0));
1907 F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
F.Scale);
1912 Immediate MaxOffset, LSRUse::KindType Kind,
1914 Immediate BaseOffset,
bool HasBaseReg, int64_t Scale) {
1917 BaseOffset, HasBaseReg, Scale) ||
1922 BaseGV, BaseOffset,
true, 0));
1926 Immediate MaxOffset, LSRUse::KindType Kind,
1927 MemAccessTy AccessTy,
const Formula &
F) {
1928 return isLegalUse(
TTI, MinOffset, MaxOffset, Kind, AccessTy,
F.BaseGV,
1929 F.BaseOffset,
F.HasBaseReg,
F.Scale);
1935 return TTI.isLegalAddScalableImmediate(
Offset.getKnownMinValue());
1937 return TTI.isLegalAddImmediate(
Offset.getFixedValue());
1941 const LSRUse &LU,
const Formula &
F) {
1943 if (LU.Kind == LSRUse::Address &&
TTI.LSRWithInstrQueries()) {
1944 for (
const LSRFixup &
Fixup : LU.Fixups)
1946 (
F.BaseOffset +
Fixup.Offset),
F.HasBaseReg,
1947 F.Scale,
Fixup.UserInst))
1953 LU.AccessTy,
F.BaseGV,
F.BaseOffset,
F.HasBaseReg,
1958 const LSRUse &LU,
const Formula &
F,
1967 return F.Scale != 1;
1970 case LSRUse::Address: {
1972 int64_t ScalableMin = 0, ScalableMax = 0, FixedMin = 0, FixedMax = 0;
1973 if (
F.BaseOffset.isScalable()) {
1974 ScalableMin = (
F.BaseOffset + LU.MinOffset).getKnownMinValue();
1975 ScalableMax = (
F.BaseOffset + LU.MaxOffset).getKnownMinValue();
1977 FixedMin = (
F.BaseOffset + LU.MinOffset).getFixedValue();
1978 FixedMax = (
F.BaseOffset + LU.MaxOffset).getFixedValue();
1982 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1985 F.HasBaseReg,
F.Scale, LU.AccessTy.AddrSpace);
1988 "Legal addressing mode has an illegal cost!");
1989 return std::max(ScaleCostMinOffset, ScaleCostMaxOffset);
1991 case LSRUse::ICmpZero:
1993 case LSRUse::Special:
2004 LSRUse::KindType Kind, MemAccessTy AccessTy,
2008 if (BaseOffset.isZero() && !BaseGV)
2013 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2017 if (!HasBaseReg && Scale == 1) {
2027 if (HasBaseReg && BaseOffset.isNonZero() && Kind != LSRUse::ICmpZero &&
2029 Opts.lsr_drop_scaled_reg_for_vscale)
2039 Immediate MaxOffset, LSRUse::KindType Kind,
2040 MemAccessTy AccessTy,
const SCEV *S,
2043 if (S->
isZero())
return true;
2056 if (BaseOffset.isZero() && !BaseGV)
2059 if (BaseOffset.isScalable())
2064 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
2067 BaseOffset, HasBaseReg, Scale);
2084 const SCEV *IncExpr;
2086 IVInc(Instruction *U,
Value *O,
const SCEV *
E)
2087 : UserInst(
U), IVOperand(
O), IncExpr(
E) {}
2094 const SCEV *ExprBase =
nullptr;
2096 IVChain() =
default;
2097 IVChain(
const IVInc &Head,
const SCEV *
Base)
2098 : Incs(1, Head), ExprBase(
Base) {}
2103 const_iterator
begin()
const {
2105 return std::next(Incs.
begin());
2107 const_iterator
end()
const {
2112 bool hasIncs()
const {
return Incs.
size() >= 2; }
2121 bool isProfitableIncrement(
const SCEV *OperExpr,
2122 const SCEV *IncExpr,
2130 SmallPtrSet<Instruction*, 4> FarUsers;
2131 SmallPtrSet<Instruction*, 4> NearUsers;
2136 const ScalarOptions &Opts;
2138 ScalarEvolution &SE;
2141 AssumptionCache &AC;
2142 TargetLibraryInfo &TLI;
2143 const TargetTransformInfo &
TTI;
2145 MemorySSAUpdater *MSSAU;
2149 bool HardwareLoopProfitable =
false;
2150 bool ShouldPreserveLCSSA =
false;
2164 SetVector<int64_t, SmallVector<int64_t, 8>, SmallSet<int64_t, 8>> Factors;
2171 SmallSetVector<Type *, 4> Types;
2177 RegUseTracker RegUses;
2182 static const unsigned MaxChains = 8;
2188 SmallPtrSet<Use*, MaxChains> IVIncSet;
2191 SmallVector<llvm::WeakVH, 2> ScalarEvolutionIVs;
2197 SmallSetVector<Instruction *, 4> InsertedNonLCSSAInsts;
2199 void OptimizeShadowIV();
2200 bool FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse);
2202 ICmpInst *OptimizeLoopTermCondToEquality(ICmpInst *
Cond,
2203 IVStrideUse *&CondUse,
2204 BasicBlock *ExitingBlock);
2205 void OptimizeLoopTermCond();
2207 void ChainInstruction(Instruction *UserInst, Instruction *IVOper,
2208 SmallVectorImpl<ChainUsers> &ChainUsersVec);
2209 void FinalizeChain(IVChain &Chain);
2210 void CollectChains();
2211 void GenerateIVChain(
const IVChain &Chain,
2212 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2214 void CollectInterestingTypesAndFactors();
2215 void CollectFixupsAndInitialFormulae();
2218 using UseMapTy = DenseMap<LSRUse::SCEVUseKindPair, size_t>;
2221 bool reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
bool HasBaseReg,
2222 LSRUse::KindType Kind, MemAccessTy AccessTy);
2224 std::pair<size_t, Immediate> getUse(
const SCEV *&Expr, LSRUse::KindType Kind,
2225 MemAccessTy AccessTy);
2227 void DeleteUse(LSRUse &LU,
size_t LUIdx);
2229 LSRUse *FindUseWithSimilarFormula(
const Formula &
F,
const LSRUse &OrigLU);
2231 void InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2232 void InsertSupplementalFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
2233 void CountRegisters(
const Formula &
F,
size_t LUIdx);
2234 bool InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F);
2235 bool IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const;
2237 void CollectLoopInvariantFixupsAndFormulae();
2239 void GenerateReassociations(LSRUse &LU,
unsigned LUIdx, Formula
Base,
2240 unsigned Depth = 0);
2242 void GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
2244 size_t Idx,
bool IsScaledReg =
false);
2245 void GenerateCombinations(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2246 void GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2247 const Formula &
Base,
size_t Idx,
2248 bool IsScaledReg =
false);
2249 void GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2250 void GenerateConstantOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
2251 const Formula &
Base,
2252 const SmallVectorImpl<Immediate> &Worklist,
2253 size_t Idx,
bool IsScaledReg =
false);
2254 void GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2255 void GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2256 void GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2257 void GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base);
2258 void GenerateCrossUseConstantOffsets();
2259 void GenerateAllReuseFormulae();
2261 void FilterOutUndesirableDedicatedRegisters();
2263 size_t EstimateSearchSpaceComplexity()
const;
2264 void NarrowSearchSpaceByDetectingSupersets();
2265 void NarrowSearchSpaceByCollapsingUnrolledCode();
2266 void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
2267 void NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
2268 void NarrowSearchSpaceByFilterPostInc();
2269 void NarrowSearchSpaceByMergingUsesOutsideLoop();
2270 void NarrowSearchSpaceByDeletingCostlyFormulas();
2271 void NarrowSearchSpaceByPickingWinnerRegs();
2272 void NarrowSearchSpaceUsingHeuristics();
2274 void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
2276 SmallVectorImpl<const Formula *> &Workspace,
2277 const Cost &CurCost,
2278 const SmallPtrSet<const SCEV *, 16> &CurRegs,
2279 DenseSet<const SCEV *> &VisitedRegs)
const;
2280 void Solve(SmallVectorImpl<const Formula *> &Solution)
const;
2284 const SmallVectorImpl<Instruction *> &Inputs)
const;
2287 const LSRUse &LU)
const;
2289 Value *Expand(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2291 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const;
2292 void RewriteForPHI(PHINode *PN,
const LSRUse &LU,
const LSRFixup &LF,
2294 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2295 void Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
const Formula &
F,
2296 SmallVectorImpl<WeakTrackingVH> &DeadInsts);
2297 void ImplementSolution(
const SmallVectorImpl<const Formula *> &Solution);
2304 LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
2305 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
2306 const TargetTransformInfo &
TTI, AssumptionCache &AC,
2307 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
2308 bool PreserveLCSSA);
2310 bool getChanged()
const {
return Changed; }
2311 const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs()
const {
2312 return ScalarEvolutionIVs;
2315 void print_factors_and_types(raw_ostream &OS)
const;
2316 void print_fixups(raw_ostream &OS)
const;
2317 void print_uses(raw_ostream &OS)
const;
2318 void print(raw_ostream &OS)
const;
2326void LSRInstance::OptimizeShadowIV() {
2336 Type *DestTy =
nullptr;
2337 bool IsSigned =
false;
2353 DestTy = UCast->getDestTy();
2357 DestTy = SCast->getDestTy();
2359 if (!DestTy)
continue;
2379 if (Mantissa == -1)
continue;
2383 unsigned Entry, Latch;
2393 if (!Init)
continue;
2394 Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
2398 BinaryOperator *Incr =
2400 if (!Incr)
continue;
2401 if (Incr->
getOpcode() != Instruction::Add
2402 && Incr->
getOpcode() != Instruction::Sub)
2406 ConstantInt *
C =
nullptr;
2418 if (!
C->getValue().isStrictlyPositive())
2426 Constant *CFP = ConstantFP::get(DestTy,
C->getZExtValue());
2428 Incr->
getOpcode() == Instruction::Add ? Instruction::FAdd
2429 : Instruction::FSub,
2446bool LSRInstance::FindIVUserForCond(Instruction *
Cond, IVStrideUse *&CondUse) {
2447 for (IVStrideUse &U : IU)
2448 if (
U.getUser() ==
Cond) {
2460ICmpInst *LSRInstance::OptimizeLoopTermCondToEquality(
2461 ICmpInst *
Cond, IVStrideUse *&CondUse, BasicBlock *ExitingBlock) {
2462 if (
Cond->isEquality() || ExitingBlock !=
L->getLoopLatch())
2466 if (!
IV || !
IV->getType()->isIntegerTy() ||
IV->getParent() !=
L->getHeader())
2474 if (!Step || Step->
isZero())
2477 const SCEV *ExitCount = SE.
getExitCount(L, ExitingBlock);
2485 const APInt &StepValue = Step->getAPInt();
2486 unsigned RecurrencePeriodLog2 =
2491 const auto *ExitValue =
2494 *
Cond, ExitValue->getAPInt() + StepValue))
2497 LLVM_DEBUG(
dbgs() <<
" Rewriting loop exit to compare " << *
IV <<
" against "
2498 << *ExitValue <<
'\n');
2501 bool TrueContinues =
L->contains(TermBr->getSuccessor(0));
2502 assert(TrueContinues !=
L->contains(TermBr->getSuccessor(1)) &&
2503 "Expected exactly one in-loop successor");
2505 auto Pred = TrueContinues ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ;
2506 auto *NewCond =
new ICmpInst(TermBr->getIterator(), Pred,
IV,
2507 ExitValue->getValue(),
"lsr.exitcond");
2508 NewCond->setDebugLoc(
Cond->getDebugLoc());
2509 TermBr->setCondition(NewCond);
2511 if (
Cond->use_empty()) {
2513 Cond->eraseFromParent();
2515 CondUse = &IU.AddUser(NewCond,
IV);
2570Instruction *LSRInstance::OptimizeMax(ICmpInst *
Cond, IVStrideUse *&CondUse) {
2585 const SCEV *IterationCount = SE.
getAddExpr(One, BackedgeTakenCount);
2586 if (IterationCount != SE.
getSCEV(Sel))
return Cond;
2592 const SCEVNAryExpr *
Max =
nullptr;
2594 Pred = ICmpInst::ICMP_SLE;
2597 Pred = ICmpInst::ICMP_SLT;
2600 Pred = ICmpInst::ICMP_ULT;
2609 if (
Max->getNumOperands() != 2)
2612 const SCEV *MaxLHS =
Max->getOperand(0);
2613 const SCEV *MaxRHS =
Max->getOperand(1);
2618 (ICmpInst::isTrueWhenEqual(Pred) ? !MaxLHS->
isZero() : (MaxLHS != One)))
2629 "Loop condition operand is an addrec in a different loop!");
2633 Value *NewRHS =
nullptr;
2634 if (ICmpInst::isTrueWhenEqual(Pred)) {
2638 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2639 NewRHS = BO->getOperand(0);
2642 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2643 NewRHS = BO->getOperand(0);
2651 NewRHS = SU->getValue();
2663 ICmpInst *NewCond =
new ICmpInst(
Cond->getIterator(), Pred,
2664 Cond->getOperand(0), NewRHS,
"scmp");
2668 Cond->replaceAllUsesWith(NewCond);
2671 Cond->eraseFromParent();
2673 if (
Cmp->use_empty()) {
2675 Cmp->eraseFromParent();
2682LSRInstance::OptimizeLoopTermCond() {
2683 SmallPtrSet<Instruction *, 4> PostIncs;
2698 SmallVector<BasicBlock*, 8> ExitingBlocks;
2699 L->getExitingBlocks(ExitingBlocks);
2707 for (BasicBlock *ExitingBlock : ExitingBlocks) {
2729 IVStrideUse *CondUse =
nullptr;
2730 if (!FindIVUserForCond(
Cond, CondUse))
2740 Cond = OptimizeMax(Cmp, CondUse);
2745 if (!DT.
dominates(ExitingBlock, LatchBlock))
2749 Cond = OptimizeLoopTermCondToEquality(Cmp, CondUse, ExitingBlock);
2753 if (LatchBlock != ExitingBlock)
2754 for (
const IVStrideUse &UI : IU)
2757 if (&UI != CondUse &&
2761 const SCEV *
A = IU.getStride(*CondUse, L);
2762 const SCEV *
B = IU.getStride(UI, L);
2763 if (!
A || !
B)
continue;
2772 if (
const SCEVConstant *
D =
2774 const ConstantInt *
C =
D->getValue();
2776 if (
C->isOne() ||
C->isMinusOne())
2777 goto decline_post_inc;
2779 if (
C->getValue().getSignificantBits() >= 64 ||
2780 C->getValue().isMinSignedValue())
2781 goto decline_post_inc;
2784 MemAccessTy AccessTy =
2786 int64_t Scale =
C->getSExtValue();
2790 AccessTy.AddrSpace))
2791 goto decline_post_inc;
2796 AccessTy.AddrSpace))
2797 goto decline_post_inc;
2802 LLVM_DEBUG(
dbgs() <<
" Change loop exiting icmp to use postinc iv: "
2810 if (
Cond->hasOneUse()) {
2816 Cond->setName(
L->getHeader()->getName() +
".termcond");
2838 IVIncInsertPos =
L->getLoopLatch()->getTerminator();
2839 for (Instruction *Inst : PostIncs)
2845bool LSRInstance::reconcileNewOffset(LSRUse &LU, Immediate NewOffset,
2846 bool HasBaseReg, LSRUse::KindType Kind,
2847 MemAccessTy AccessTy) {
2848 Immediate NewMinOffset = LU.MinOffset;
2849 Immediate NewMaxOffset = LU.MaxOffset;
2850 MemAccessTy NewAccessTy = AccessTy;
2855 if (LU.Kind != Kind)
2861 if (Kind == LSRUse::Address) {
2862 if (AccessTy.MemTy != LU.AccessTy.MemTy) {
2863 NewAccessTy = MemAccessTy::getUnknown(AccessTy.MemTy->
getContext(),
2864 AccessTy.AddrSpace);
2869 if (Immediate::isKnownLT(NewOffset, LU.MinOffset)) {
2871 LU.MaxOffset - NewOffset, HasBaseReg))
2873 NewMinOffset = NewOffset;
2874 }
else if (Immediate::isKnownGT(NewOffset, LU.MaxOffset)) {
2876 NewOffset - LU.MinOffset, HasBaseReg))
2878 NewMaxOffset = NewOffset;
2884 if (NewAccessTy.MemTy && NewAccessTy.MemTy->
isVoidTy() &&
2885 (NewMinOffset.isScalable() || NewMaxOffset.isScalable()))
2889 LU.MinOffset = NewMinOffset;
2890 LU.MaxOffset = NewMaxOffset;
2891 LU.AccessTy = NewAccessTy;
2898std::pair<size_t, Immediate> LSRInstance::getUse(
const SCEV *&Expr,
2899 LSRUse::KindType Kind,
2900 MemAccessTy AccessTy) {
2901 const SCEV *
Copy = Expr;
2904 Opts, ExprUse, SE, AccessTy.MemTy && AccessTy.MemTy->
isScalableTy());
2911 Offset = Immediate::getFixed(0);
2914 std::pair<UseMapTy::iterator, bool>
P =
2915 UseMap.
try_emplace(LSRUse::SCEVUseKindPair(Expr, Kind));
2918 size_t LUIdx =
P.first->second;
2919 LSRUse &LU =
Uses[LUIdx];
2920 if (reconcileNewOffset(LU,
Offset,
true, Kind, AccessTy))
2922 return std::make_pair(LUIdx,
Offset);
2926 size_t LUIdx =
Uses.size();
2927 P.first->second = LUIdx;
2928 Uses.push_back(LSRUse(Kind, AccessTy));
2929 LSRUse &LU =
Uses[LUIdx];
2933 return std::make_pair(LUIdx,
Offset);
2937void LSRInstance::DeleteUse(LSRUse &LU,
size_t LUIdx) {
2938 if (&LU != &
Uses.back())
2943 RegUses.swapAndDropUse(LUIdx,
Uses.size());
2949LSRInstance::FindUseWithSimilarFormula(
const Formula &OrigF,
2950 const LSRUse &OrigLU) {
2952 for (LSRUse &LU :
Uses) {
2958 if (&LU != &OrigLU && LU.Kind != LSRUse::ICmpZero &&
2959 LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
2960 LU.HasFormulaWithSameRegs(OrigF)) {
2962 for (
const Formula &
F : LU.Formulae) {
2965 if (
F.BaseRegs == OrigF.BaseRegs &&
2966 F.ScaledReg == OrigF.ScaledReg &&
2967 F.BaseGV == OrigF.BaseGV &&
2968 F.Scale == OrigF.Scale &&
2969 F.UnfoldedOffset == OrigF.UnfoldedOffset) {
2970 if (
F.BaseOffset.isZero())
2985void LSRInstance::CollectInterestingTypesAndFactors() {
2986 SmallSetVector<const SCEV *, 4> Strides;
2990 for (
const IVStrideUse &U : IU) {
2991 const SCEV *Expr = IU.getExpr(U);
3009 }
while (!Worklist.
empty());
3013 for (SmallSetVector<const SCEV *, 4>::const_iterator
3015 for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
3016 std::next(
I); NewStrideIter !=
E; ++NewStrideIter) {
3017 const SCEV *OldStride = *
I;
3018 const SCEV *NewStride = *NewStrideIter;
3028 if (
const SCEVConstant *Factor =
3031 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
3032 Factors.insert(Factor->getAPInt().getSExtValue());
3033 }
else if (
const SCEVConstant *Factor =
3037 if (Factor->getAPInt().getSignificantBits() <= 64 && !Factor->isZero())
3038 Factors.insert(Factor->getAPInt().getSExtValue());
3044 if (Types.size() == 1)
3056 for(; OI != OE; ++OI) {
3075 return Trunc->getOperand(0);
3108 if (SubExpr->getSCEVType() ==
scAddExpr)
3111 if (SubExpr->getSCEVType() !=
scMulExpr)
3127bool IVChain::isProfitableIncrement(
const SCEV *OperExpr,
3128 const SCEV *IncExpr,
3129 ScalarEvolution &SE) {
3138 SmallPtrSet<const SCEV*, 8> Processed;
3156 if (!Chain.hasIncs())
3159 if (!
Users.empty()) {
3160 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" users:\n";
3162 :
Users) {
dbgs() <<
" " << *Inst <<
"\n"; });
3165 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3174 && SE.
getSCEV(Chain.tailUserInst()) == Chain.Incs[0].IncExpr) {
3177 const SCEV *LastIncExpr =
nullptr;
3178 unsigned NumConstIncrements = 0;
3179 unsigned NumVarIncrements = 0;
3180 unsigned NumReusedIncrements = 0;
3182 if (
TTI.isProfitableLSRChainElement(Chain.Incs[0].UserInst))
3185 for (
const IVInc &Inc : Chain) {
3186 if (
TTI.isProfitableLSRChainElement(Inc.UserInst))
3188 if (Inc.IncExpr->isZero())
3194 ++NumConstIncrements;
3198 if (Inc.IncExpr == LastIncExpr)
3199 ++NumReusedIncrements;
3203 LastIncExpr = Inc.IncExpr;
3208 if (NumConstIncrements > 1)
3215 cost += NumVarIncrements;
3219 cost -= NumReusedIncrements;
3221 LLVM_DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" Cost: " << cost
3228void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
3229 SmallVectorImpl<ChainUsers> &ChainUsersVec) {
3233 const SCEV *
const OperExpr = SE.
getSCEV(NextIV);
3234 const SCEV *
const OperExprBase =
getExprBase(OperExpr);
3238 unsigned ChainIdx = 0, NChains = IVChainVec.size();
3239 const SCEV *LastIncExpr =
nullptr;
3240 for (; ChainIdx < NChains; ++ChainIdx) {
3241 IVChain &Chain = IVChainVec[ChainIdx];
3259 const SCEV *PrevExpr = SE.
getSCEV(PrevIV);
3260 const SCEV *IncExpr = SE.
getMinusSCEV(OperExpr, PrevExpr);
3266 Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
3267 LastIncExpr = IncExpr;
3273 if (ChainIdx == NChains) {
3280 LastIncExpr = OperExpr;
3287 IVChainVec.push_back(IVChain(IVInc(UserInst, IVOper, LastIncExpr),
3289 ChainUsersVec.
resize(NChains);
3290 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Head: (" << *UserInst
3291 <<
") IV=" << *LastIncExpr <<
"\n");
3293 LLVM_DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Inc: (" << *UserInst
3294 <<
") IV+" << *LastIncExpr <<
"\n");
3296 IVChainVec[ChainIdx].add(IVInc(UserInst, IVOper, LastIncExpr));
3298 IVChain &Chain = IVChainVec[ChainIdx];
3300 SmallPtrSet<Instruction*,4> &NearUsers = ChainUsersVec[ChainIdx].NearUsers;
3302 if (!LastIncExpr->
isZero()) {
3303 ChainUsersVec[ChainIdx].FarUsers.insert_range(NearUsers);
3312 for (User *U : IVOper->
users()) {
3318 IVChain::const_iterator IncIter = Chain.Incs.begin();
3319 IVChain::const_iterator IncEnd = Chain.Incs.end();
3320 for( ; IncIter != IncEnd; ++IncIter) {
3321 if (IncIter->UserInst == OtherUse)
3324 if (IncIter != IncEnd)
3329 && IU.isIVUserOrOperand(OtherUse)) {
3332 NearUsers.
insert(OtherUse);
3337 ChainUsersVec[ChainIdx].FarUsers.
erase(UserInst);
3362void LSRInstance::CollectChains() {
3366 SmallVector<BasicBlock *,8> LatchPath;
3369 Rung->
getBlock() != LoopHeader; Rung = Rung->getIDom()) {
3375 for (BasicBlock *BB :
reverse(LatchPath)) {
3376 for (Instruction &
I : *BB) {
3382 if (IU.isEphemeral(&
I))
3392 for (
unsigned ChainIdx = 0, NChains = IVChainVec.size();
3393 ChainIdx < NChains; ++ChainIdx) {
3394 ChainUsersVec[ChainIdx].NearUsers.
erase(&
I);
3397 SmallPtrSet<Instruction*, 4> UniqueOperands;
3400 while (IVOpIter != IVOpEnd) {
3402 if (UniqueOperands.
insert(IVOpInst).second)
3403 ChainInstruction(&
I, IVOpInst, ChainUsersVec);
3404 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3409 for (PHINode &PN :
L->getHeader()->phis()) {
3416 ChainInstruction(&PN, IncV, ChainUsersVec);
3419 unsigned ChainIdx = 0;
3420 for (
unsigned UsersIdx = 0, NChains = IVChainVec.size();
3421 UsersIdx < NChains; ++UsersIdx) {
3424 ChainUsersVec[UsersIdx].FarUsers, SE,
TTI))
3427 if (ChainIdx != UsersIdx)
3428 IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
3429 FinalizeChain(IVChainVec[ChainIdx]);
3432 IVChainVec.resize(ChainIdx);
3435void LSRInstance::FinalizeChain(IVChain &Chain) {
3436 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
3437 LLVM_DEBUG(
dbgs() <<
"Final Chain: " << *Chain.Incs[0].UserInst <<
"\n");
3439 for (
const IVInc &Inc : Chain) {
3441 auto UseI =
find(Inc.UserInst->operands(), Inc.IVOperand);
3442 assert(UseI != Inc.UserInst->op_end() &&
"cannot find IV operand");
3443 IVIncSet.insert(UseI);
3452 Immediate IncOffset = Immediate::getZero();
3461 C->getSignificantBits() > 64)
3463 IncOffset = Immediate::getScalable(
C->getSExtValue());
3471 nullptr, IncOffset,
false))
3479void LSRInstance::GenerateIVChain(
const IVChain &Chain,
3480 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
3483 const IVInc &Head = Chain.Incs[0];
3488 Value *IVSrc =
nullptr;
3489 while (IVOpIter != IVOpEnd) {
3500 if (SE.
getSCEV(*IVOpIter) == Head.IncExpr
3501 || SE.
getSCEV(IVSrc) == Head.IncExpr) {
3504 IVOpIter =
findIVOperand(std::next(IVOpIter), IVOpEnd, L, SE);
3506 if (IVOpIter == IVOpEnd) {
3508 LLVM_DEBUG(
dbgs() <<
"Concealed chain head: " << *Head.UserInst <<
"\n");
3511 assert(IVSrc &&
"Failed to find IV chain source");
3516 const SCEV *LeftOverExpr =
nullptr;
3517 const SCEV *Accum = SE.
getZero(IntTy);
3521 for (
const IVInc &Inc : Chain) {
3524 InsertPt =
L->getLoopLatch()->getTerminator();
3528 Value *IVOper = IVSrc;
3529 if (!Inc.IncExpr->isZero()) {
3534 LeftOverExpr = LeftOverExpr
3540 bool FoundBase =
false;
3541 for (
auto [MapScev, MapIVOper] :
reverse(Bases)) {
3542 const SCEV *Remainder = SE.
getMinusSCEV(Accum, MapScev);
3544 if (!Remainder->
isZero()) {
3546 Value *IncV =
Rewriter.expandCodeFor(Remainder, IntTy, InsertPt);
3547 const SCEV *IVOperExpr =
3549 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3558 if (!FoundBase && LeftOverExpr && !LeftOverExpr->
isZero()) {
3561 Value *IncV =
Rewriter.expandCodeFor(LeftOverExpr, IntTy, InsertPt);
3564 IVOper =
Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
3569 assert(IVTy == IVOper->
getType() &&
"inconsistent IV increment type");
3572 LeftOverExpr =
nullptr;
3576 if (IVTy != OperTy) {
3578 "cannot extend a chained IV");
3580 IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy,
"lsr.chain");
3582 Inc.UserInst->replaceUsesOfWith(Inc.IVOperand, IVOper);
3589 for (PHINode &Phi :
L->getHeader()->phis()) {
3593 Phi.getIncomingValueForBlock(
L->getLoopLatch()));
3596 Value *IVOper = IVSrc;
3598 if (IVTy != PostIncTy) {
3600 IRBuilder<> Builder(
L->getLoopLatch()->getTerminator());
3601 Builder.SetCurrentDebugLocation(PostIncV->
getDebugLoc());
3602 IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy,
"lsr.chain");
3604 Phi.replaceUsesOfWith(PostIncV, IVOper);
3610void LSRInstance::CollectFixupsAndInitialFormulae() {
3611 CondBrInst *ExitBranch =
nullptr;
3612 bool SaveCmp =
TTI.
canSaveCmp(L, &ExitBranch, &SE, &LI, &DT, &AC, &TLI);
3615 SmallPtrSet<const SCEV *, 16> Regs;
3616 DenseSet<const SCEV *> VisitedRegs;
3617 DenseSet<size_t> VisitedLSRUse;
3619 for (
const IVStrideUse &U : IU) {
3624 assert(UseI != UserInst->
op_end() &&
"cannot find IV operand");
3625 if (IVIncSet.count(UseI)) {
3626 LLVM_DEBUG(
dbgs() <<
"Use is in profitable chain: " << **UseI <<
'\n');
3630 LSRUse::KindType
Kind = LSRUse::Basic;
3631 MemAccessTy AccessTy;
3633 Kind = LSRUse::Address;
3637 const SCEV *S = IU.getExpr(U);
3653 if (CI->isEquality()) {
3656 Value *
NV = CI->getOperand(1);
3657 if (NV ==
U.getOperandValToReplace()) {
3658 CI->setOperand(1, CI->getOperand(0));
3659 CI->setOperand(0, NV);
3660 NV = CI->getOperand(1);
3667 (!
NV->getType()->isPointerTy() ||
3674 Kind = LSRUse::ICmpZero;
3676 }
else if (
L->isLoopInvariant(NV) &&
3679 !
NV->getType()->isPointerTy()) {
3690 Kind = LSRUse::ICmpZero;
3697 for (
size_t i = 0, e = Factors.size(); i != e; ++i)
3698 if (Factors[i] != -1)
3699 Factors.insert(-(
uint64_t)Factors[i]);
3705 std::pair<size_t, Immediate>
P = getUse(S, Kind, AccessTy);
3706 size_t LUIdx =
P.first;
3708 LSRUse &LU =
Uses[LUIdx];
3711 LSRFixup &LF = LU.getNewFixup();
3712 LF.UserInst = UserInst;
3713 LF.OperandValToReplace =
U.getOperandValToReplace();
3714 LF.PostIncLoops = TmpPostIncLoops;
3716 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3717 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3720 if (!VisitedLSRUse.
count(LUIdx) && !LF.isUseFullyOutsideLoop(L)) {
3722 F.initialMatch(S, L, SE);
3723 BaselineCost.RateFormula(
F, Regs, VisitedRegs, LU,
3724 HardwareLoopProfitable);
3725 VisitedLSRUse.
insert(LUIdx);
3729 if (LU.Formulae.empty()) {
3730 InsertInitialFormula(S, LU, LUIdx);
3731 CountRegisters(LU.Formulae.back(), LUIdx);
3740void LSRInstance::InsertInitialFormula(
const SCEV *S, LSRUse &LU,
3744 LU.RigidFormula =
true;
3747 F.initialMatch(S, L, SE);
3748 bool Inserted = InsertFormula(LU, LUIdx,
F);
3749 assert(Inserted &&
"Initial formula already exists!"); (void)Inserted;
3755LSRInstance::InsertSupplementalFormula(
const SCEV *S,
3756 LSRUse &LU,
size_t LUIdx) {
3758 F.BaseRegs.push_back(S);
3759 F.HasBaseReg =
true;
3760 bool Inserted = InsertFormula(LU, LUIdx,
F);
3761 assert(Inserted &&
"Supplemental formula already exists!"); (void)Inserted;
3765void LSRInstance::CountRegisters(
const Formula &
F,
size_t LUIdx) {
3767 RegUses.countRegister(
F.ScaledReg, LUIdx);
3768 for (
const SCEV *BaseReg :
F.BaseRegs)
3769 RegUses.countRegister(BaseReg, LUIdx);
3774bool LSRInstance::InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &
F) {
3777 "Formula is illegal");
3779 if (!LU.InsertFormula(
F, *L))
3782 CountRegisters(
F, LUIdx);
3788bool LSRInstance::IsFixupExecutedEachIncrement(
const LSRFixup &LF)
const {
3800LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
3802 SmallPtrSet<const SCEV *, 32> Visited;
3809 while (!Worklist.
empty()) {
3813 if (!Visited.
insert(S).second)
3824 const Value *
V = US->getValue();
3827 if (
L->contains(Inst))
continue;
3831 for (
const Use &U :
V->uses()) {
3841 if (UserInst->
getParent()->getParent() !=
L->getHeader()->getParent())
3863 bool HasIncompatibleEHPTerminatedBlock =
false;
3865 for (
unsigned int I = 0;
I < PhiNode->getNumIncomingValues();
I++) {
3866 if (PhiNode->getIncomingValue(
I) == ExpectedValue) {
3867 if (PhiNode->getIncomingBlock(
I)->getTerminator()->isEHPad()) {
3868 HasIncompatibleEHPTerminatedBlock =
true;
3873 if (HasIncompatibleEHPTerminatedBlock) {
3896 unsigned OtherIdx = !
U.getOperandNo();
3897 Value *OtherOp = ICI->getOperand(OtherIdx);
3907 std::pair<size_t, Immediate>
P =
3908 getUse(S, LSRUse::Basic, MemAccessTy());
3909 size_t LUIdx =
P.first;
3911 LSRUse &LU =
Uses[LUIdx];
3912 LSRFixup &LF = LU.getNewFixup();
3913 LF.UserInst =
const_cast<Instruction *
>(UserInst);
3914 LF.OperandValToReplace =
U;
3916 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3917 LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
3918 InsertSupplementalFormula(US, LU, LUIdx);
3919 CountRegisters(LU.Formulae.back(),
Uses.size() - 1);
3935 unsigned Depth = 0) {
3942 for (
const SCEV *S :
Add->operands()) {
3949 const SCEV *Start, *Step;
3954 if (Start->isZero())
3963 Remainder =
nullptr;
3965 if (Remainder != Start) {
3987 LSRUse &LU,
const SCEV *S,
const Loop *L,
3989 if (LU.Kind != LSRUse::Address ||
3990 !LU.AccessTy.getType()->isIntOrIntVectorTy())
3996 if (
TTI.isIndexedLoadLegal(
TTI.MIM_PostInc, S->
getType()) ||
4005void LSRInstance::GenerateReassociationsImpl(LSRUse &LU,
unsigned LUIdx,
4006 const Formula &
Base,
4007 unsigned Depth,
size_t Idx,
4017 const SCEV *Remainder =
CollectSubexprs(BaseReg,
nullptr, AddOps, L, SE);
4021 if (AddOps.
size() == 1)
4035 LU.AccessTy, *J,
Base.getNumRegs() > 1))
4040 InnerAddOps.append(std::next(J), std::as_const(AddOps).
end());
4044 if (InnerAddOps.size() == 1 &&
4046 LU.AccessTy, InnerAddOps[0],
Base.getNumRegs() > 1))
4049 const SCEV *InnerSum = SE.
getAddExpr(InnerAddOps);
4054 if (
F.UnfoldedOffset.isNonZero() &&
F.UnfoldedOffset.isScalable())
4063 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
4066 F.ScaledReg =
nullptr;
4069 F.BaseRegs.erase(
F.BaseRegs.begin() + Idx);
4070 }
else if (IsScaledReg)
4071 F.ScaledReg = InnerSum;
4073 F.BaseRegs[
Idx] = InnerSum;
4081 Immediate::getFixed((
uint64_t)
F.UnfoldedOffset.getFixedValue() +
4084 F.BaseRegs.push_back(*J);
4089 if (InsertFormula(LU, LUIdx,
F))
4096 GenerateReassociations(LU, LUIdx, LU.Formulae.back(),
4102void LSRInstance::GenerateReassociations(LSRUse &LU,
unsigned LUIdx,
4104 assert(
Base.isCanonical(*L) &&
"Input must be in the canonical form");
4109 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4110 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth, i);
4112 if (
Base.Scale == 1)
4113 GenerateReassociationsImpl(LU, LUIdx,
Base,
Depth,
4119void LSRInstance::GenerateCombinations(LSRUse &LU,
unsigned LUIdx,
4122 if (
Base.BaseRegs.size() + (
Base.Scale == 1) +
4123 (
Base.UnfoldedOffset.isNonZero()) <=
4131 Formula NewBase =
Base;
4132 NewBase.BaseRegs.clear();
4133 Type *CombinedIntegerType =
nullptr;
4134 for (
const SCEV *BaseReg :
Base.BaseRegs) {
4137 if (!CombinedIntegerType)
4139 Ops.push_back(BaseReg);
4142 NewBase.BaseRegs.push_back(BaseReg);
4146 if (
Ops.size() == 0)
4151 auto GenerateFormula = [&](
const SCEV *Sum) {
4152 Formula
F = NewBase;
4160 F.BaseRegs.push_back(Sum);
4162 (void)InsertFormula(LU, LUIdx,
F);
4166 if (
Ops.size() > 1) {
4173 if (NewBase.UnfoldedOffset.isNonZero() && NewBase.UnfoldedOffset.isFixed()) {
4174 assert(CombinedIntegerType &&
"Missing a type for the unfolded offset");
4176 NewBase.UnfoldedOffset.getFixedValue(),
true));
4177 NewBase.UnfoldedOffset = Immediate::getFixed(0);
4183void LSRInstance::GenerateSymbolicOffsetsImpl(LSRUse &LU,
unsigned LUIdx,
4184 const Formula &
Base,
size_t Idx,
4188 if (
G->isZero() || !GV)
4192 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4197 F.BaseRegs[
Idx] =
G;
4198 (void)InsertFormula(LU, LUIdx,
F);
4202void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx,
4205 if (
Base.BaseGV)
return;
4207 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4208 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, i);
4209 if (
Base.Scale == 1)
4210 GenerateSymbolicOffsetsImpl(LU, LUIdx,
Base, -1,
4215void LSRInstance::GenerateConstantOffsetsImpl(
4216 LSRUse &LU,
unsigned LUIdx,
const Formula &
Base,
4217 const SmallVectorImpl<Immediate> &Worklist,
size_t Idx,
bool IsScaledReg) {
4219 auto GenerateOffset = [&](
const SCEV *
G, Immediate
Offset) {
4221 if (!
Base.BaseOffset.isCompatibleImmediate(
Offset))
4223 F.BaseOffset =
Base.BaseOffset.subUnsigned(
Offset);
4225 if (
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F)) {
4227 const SCEV *NewOffset =
Offset.getSCEV(SE,
G->getType());
4233 F.ScaledReg =
nullptr;
4235 F.deleteBaseReg(
F.BaseRegs[Idx]);
4237 }
else if (IsScaledReg)
4240 F.BaseRegs[
Idx] = NewG;
4242 (void)InsertFormula(LU, LUIdx,
F);
4257 const APInt *StepInt;
4262 for (Immediate
Offset : Worklist) {
4264 Offset = Immediate::getFixed(
Offset.getFixedValue() - Step);
4270 for (Immediate
Offset : Worklist)
4277 if (
G->isZero() ||
Imm.isZero() ||
4278 !
Base.BaseOffset.isCompatibleImmediate(
Imm))
4281 F.BaseOffset =
F.BaseOffset.addUnsigned(
Imm);
4282 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
F))
4287 F.BaseRegs[
Idx] =
G;
4292 (void)InsertFormula(LU, LUIdx,
F);
4296void LSRInstance::GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx,
4302 if (LU.MaxOffset != LU.MinOffset)
4305 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i)
4306 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, i);
4307 if (
Base.Scale == 1)
4308 GenerateConstantOffsetsImpl(LU, LUIdx,
Base, Worklist, -1,
4314void LSRInstance::GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx,
4316 if (LU.Kind != LSRUse::ICmpZero)
return;
4324 if (LU.MinOffset != LU.MaxOffset)
return;
4327 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4329 for (
const SCEV *BaseReg :
Base.BaseRegs)
4330 if (
BaseReg->getType()->isPointerTy())
4332 assert(!
Base.BaseGV &&
"ICmpZero use is not legal!");
4335 for (int64_t Factor : Factors) {
4340 if (
Base.BaseOffset.isMin() && Factor == -1)
4343 if (
Base.BaseOffset.isNonZero() &&
Base.BaseOffset.isScalable())
4345 Immediate NewBaseOffset =
Base.BaseOffset.mulUnsigned(Factor);
4346 assert(Factor != 0 &&
"Zero factor not expected!");
4347 if (NewBaseOffset.getFixedValue() / Factor !=
4348 Base.BaseOffset.getFixedValue())
4356 Immediate
Offset = LU.MinOffset;
4357 if (
Offset.isMin() && Factor == -1)
4360 if (
Offset.getFixedValue() / Factor != LU.MinOffset.getFixedValue())
4368 F.BaseOffset = NewBaseOffset;
4375 F.BaseOffset =
F.BaseOffset.addUnsigned(
Offset).subUnsigned(LU.MinOffset);
4377 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4380 for (
size_t i = 0, e =
F.BaseRegs.size(); i != e; ++i) {
4394 if (
F.UnfoldedOffset.isNonZero()) {
4395 if (
F.UnfoldedOffset.isMin() && Factor == -1)
4397 F.UnfoldedOffset =
F.UnfoldedOffset.mulUnsigned(Factor);
4398 if (
F.UnfoldedOffset.getFixedValue() / Factor !=
4399 Base.UnfoldedOffset.getFixedValue())
4403 IntTy,
F.UnfoldedOffset.getFixedValue()))
4408 (void)InsertFormula(LU, LUIdx,
F);
4415void LSRInstance::GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4422 if (
Base.Scale != 0 && !
Base.unscale())
4425 assert(
Base.Scale == 0 &&
"unscale did not did its job!");
4428 for (int64_t Factor : Factors) {
4429 Base.Scale = Factor;
4430 Base.HasBaseReg =
Base.BaseRegs.size() > 1;
4432 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4436 if (LU.Kind == LSRUse::Basic &&
4437 isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
4438 LU.AccessTy,
Base) &&
4439 LU.AllFixupsOutsideLoop)
4440 LU.Kind = LSRUse::Special;
4446 if (LU.Kind == LSRUse::ICmpZero && !
Base.HasBaseReg &&
4447 Base.BaseOffset.isZero() && !
Base.BaseGV)
4450 for (
size_t i = 0, e =
Base.BaseRegs.size(); i != e; ++i) {
4452 if (AR && (AR->
getLoop() == L || LU.AllFixupsOutsideLoop)) {
4453 const SCEV *FactorS = SE.
getConstant(IntTy, Factor);
4458 if (
const SCEV *Quotient =
getExactSDiv(AR, FactorS, SE,
true))
4459 if (!Quotient->isZero()) {
4462 F.ScaledReg = Quotient;
4463 F.deleteBaseReg(
F.BaseRegs[i]);
4467 if (
F.Scale == 1 && (
F.BaseRegs.empty() ||
4468 (AR->
getLoop() != L && LU.AllFixupsOutsideLoop)))
4472 if (
F.Scale == 1 && LU.AllFixupsOutsideLoop)
4474 (void)InsertFormula(LU, LUIdx,
F);
4490 const SCEV *Result =
nullptr;
4491 for (
auto &L :
Loops) {
4495 if (!New || (Result && New != Result))
4500 assert(Result &&
"failed to create expression");
4505void LSRInstance::GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula
Base) {
4507 if (
Base.BaseGV)
return;
4517 if (
Base.ScaledReg &&
Base.ScaledReg->getType()->isPointerTy())
4520 [](
const SCEV *S) { return S->getType()->isPointerTy(); }))
4524 for (
auto &LF : LU.Fixups)
4525 Loops.push_back(LF.PostIncLoops);
4527 for (
Type *SrcTy : Types) {
4536 const SCEV *NewScaledReg =
4538 if (!NewScaledReg || NewScaledReg->
isZero())
4540 F.ScaledReg = NewScaledReg;
4542 bool HasZeroBaseReg =
false;
4543 for (
const SCEV *&BaseReg :
F.BaseRegs) {
4544 const SCEV *NewBaseReg =
4546 if (!NewBaseReg || NewBaseReg->
isZero()) {
4547 HasZeroBaseReg =
true;
4557 if (!
F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
4561 (void)InsertFormula(LU, LUIdx,
F);
4574 const SCEV *OrigReg;
4576 WorkItem(
size_t LI, Immediate
I,
const SCEV *R)
4577 : LUIdx(LI),
Imm(
I), OrigReg(
R) {}
4579 void print(raw_ostream &OS)
const;
4585#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4586void WorkItem::print(raw_ostream &OS)
const {
4587 OS <<
"in formulae referencing " << *OrigReg <<
" in use " << LUIdx
4588 <<
" , add offset " <<
Imm;
4598void LSRInstance::GenerateCrossUseConstantOffsets() {
4600 using ImmMapTy = std::map<Immediate, const SCEV *, KeyOrderTargetImmediate>;
4602 DenseMap<const SCEV *, ImmMapTy>
Map;
4603 DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
4605 for (
const SCEV *Use : RegUses) {
4609 auto Pair =
Map.try_emplace(
Reg);
4612 Pair.first->second.insert(std::make_pair(
Imm, Use));
4613 UsedByIndicesMap[
Reg] |= RegUses.getUsedByIndices(Use);
4620 SmallSet<std::pair<size_t, Immediate>, 32, KeyOrderSizeTAndImmediate>
4622 for (
const SCEV *
Reg : Sequence) {
4623 const ImmMapTy &Imms =
Map.find(
Reg)->second;
4626 if (Imms.size() == 1)
4630 for (
const auto &Entry
4632 <<
' ' <<
Entry.first;
4636 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
4638 const SCEV *OrigReg = J->second;
4640 Immediate JImm = J->first;
4641 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
4644 UsedByIndicesMap[
Reg].
count() == 1) {
4652 Immediate
First = Imms.begin()->first;
4653 Immediate
Last = std::prev(Imms.end())->first;
4654 if (!
First.isCompatibleImmediate(
Last)) {
4661 bool Scalable =
First.isScalable() ||
Last.isScalable();
4662 int64_t FI =
First.getKnownMinValue();
4663 int64_t LI =
Last.getKnownMinValue();
4666 int64_t Avg = (FI & LI) + ((FI ^ LI) >> 1);
4669 Avg = Avg + ((FI ^ LI) & ((
uint64_t)Avg >> 63));
4670 ImmMapTy::const_iterator OtherImms[] = {
4671 Imms.begin(), std::prev(Imms.end()),
4672 Imms.lower_bound(Immediate::get(Avg, Scalable))};
4673 for (
const auto &M : OtherImms) {
4674 if (M == J || M == JE)
continue;
4675 if (!JImm.isCompatibleImmediate(
M->first))
4679 Immediate
Imm = JImm.subUnsigned(
M->first);
4680 for (
unsigned LUIdx : UsedByIndices.
set_bits())
4682 if (UniqueItems.
insert(std::make_pair(LUIdx,
Imm)).second)
4690 UsedByIndicesMap.
clear();
4691 UniqueItems.
clear();
4694 for (
const WorkItem &WI : WorkItems) {
4695 size_t LUIdx = WI.LUIdx;
4696 LSRUse &LU =
Uses[LUIdx];
4697 Immediate
Imm = WI.Imm;
4698 const SCEV *OrigReg = WI.OrigReg;
4701 const SCEV *NegImmS =
Imm.getNegativeSCEV(SE, IntTy);
4705 for (
size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
4706 Formula
F = LU.Formulae[
L];
4713 if (
F.ScaledReg == OrigReg) {
4714 if (!
F.BaseOffset.isCompatibleImmediate(
Imm))
4716 Immediate
Offset =
F.BaseOffset.addUnsigned(
Imm.mulUnsigned(
F.Scale));
4718 const SCEV *S =
Offset.getNegativeSCEV(SE, IntTy);
4719 if (
F.referencesReg(S))
4722 NewF.BaseOffset =
Offset;
4723 if (!
isLegalUse(
TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4726 NewF.ScaledReg = SE.
getAddExpr(NegImmS, NewF.ScaledReg);
4735 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4737 if (
C->getValue()->isNegative() !=
4738 (NewF.BaseOffset.isLessThanZero()) &&
4739 (
C->getAPInt().abs() * APInt(
BitWidth,
F.Scale))
4740 .ule(std::abs(NewF.BaseOffset.getFixedValue())))
4745 NewF.canonicalize(*this->L);
4746 (void)InsertFormula(LU, LUIdx, NewF);
4749 for (
size_t N = 0, NE =
F.BaseRegs.size();
N != NE; ++
N) {
4751 if (BaseReg != OrigReg)
4754 if (!NewF.BaseOffset.isCompatibleImmediate(
Imm) ||
4755 !NewF.UnfoldedOffset.isCompatibleImmediate(
Imm) ||
4756 !NewF.BaseOffset.isCompatibleImmediate(NewF.UnfoldedOffset))
4758 NewF.BaseOffset = NewF.BaseOffset.addUnsigned(
Imm);
4760 LU.Kind, LU.AccessTy, NewF)) {
4764 Immediate NewUnfoldedOffset = NewF.UnfoldedOffset.addUnsigned(
Imm);
4768 NewF.UnfoldedOffset = NewUnfoldedOffset;
4770 NewF.BaseRegs[
N] = SE.
getAddExpr(NegImmS, BaseReg);
4775 for (
const SCEV *NewReg : NewF.BaseRegs)
4777 if (NewF.BaseOffset.isNonZero() && NewF.BaseOffset.isScalable())
4779 if ((
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4781 .slt(std::abs(NewF.BaseOffset.getFixedValue())) &&
4782 (
C->getAPInt() + NewF.BaseOffset.getFixedValue())
4785 NewF.BaseOffset.getFixedValue()))
4790 NewF.canonicalize(*this->L);
4791 (void)InsertFormula(LU, LUIdx, NewF);
4802LSRInstance::GenerateAllReuseFormulae() {
4805 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4806 LSRUse &LU =
Uses[LUIdx];
4807 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4808 GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
4809 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4810 GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
4812 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4813 LSRUse &LU =
Uses[LUIdx];
4814 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4815 GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
4816 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4817 GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
4818 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4819 GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
4820 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4821 GenerateScales(LU, LUIdx, LU.Formulae[i]);
4823 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4824 LSRUse &LU =
Uses[LUIdx];
4825 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
4826 GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
4829 GenerateCrossUseConstantOffsets();
4832 "After generating reuse formulae:\n";
4833 print_uses(
dbgs()));
4838void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
4839 DenseSet<const SCEV *> VisitedRegs;
4840 SmallPtrSet<const SCEV *, 16> Regs;
4841 SmallPtrSet<const SCEV *, 16> LoserRegs;
4843 bool ChangedFormulae =
false;
4848 using BestFormulaeTy = DenseMap<SmallVector<const SCEV *, 4>,
size_t>;
4850 BestFormulaeTy BestFormulae;
4852 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4853 LSRUse &LU =
Uses[LUIdx];
4858 for (
size_t FIdx = 0, NumForms = LU.Formulae.size();
4859 FIdx != NumForms; ++FIdx) {
4860 Formula &
F = LU.Formulae[FIdx];
4869 Cost CostF(Opts, L, SE,
TTI, AMK);
4871 CostF.RateFormula(
F, Regs, VisitedRegs, LU, HardwareLoopProfitable,
4873 if (CostF.isLoser()) {
4885 for (
const SCEV *
Reg :
F.BaseRegs) {
4886 if (RegUses.isRegUsedByUsesOtherThan(
Reg, LUIdx))
4890 RegUses.isRegUsedByUsesOtherThan(
F.ScaledReg, LUIdx))
4891 Key.push_back(
F.ScaledReg);
4896 std::pair<BestFormulaeTy::const_iterator, bool>
P =
4897 BestFormulae.insert(std::make_pair(
Key, FIdx));
4901 Formula &Best = LU.Formulae[
P.first->second];
4903 Cost CostBest(Opts, L, SE,
TTI, AMK);
4905 CostBest.RateFormula(Best, Regs, VisitedRegs, LU,
4906 HardwareLoopProfitable);
4907 if (CostF.isLess(CostBest))
4911 " in favor of formula ";
4912 Best.print(
dbgs());
dbgs() <<
'\n');
4915 ChangedFormulae =
true;
4917 LU.DeleteFormula(
F);
4925 LU.RecomputeRegs(LUIdx, RegUses);
4928 BestFormulae.clear();
4933 "After filtering out undesirable candidates:\n";
4941size_t LSRInstance::EstimateSearchSpaceComplexity()
const {
4943 for (
const LSRUse &LU :
Uses) {
4944 size_t FSize = LU.Formulae.size();
4945 if (FSize >= Opts.lsr_complexity_limit) {
4946 Power = Opts.lsr_complexity_limit;
4950 if (Power >= Opts.lsr_complexity_limit)
4959void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
4960 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
4963 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by eliminating formulae "
4964 "which use a superset of registers used by other "
4967 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
4968 LSRUse &LU =
Uses[LUIdx];
4970 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
4971 Formula &
F = LU.Formulae[i];
4972 if (
F.BaseOffset.isNonZero() &&
F.BaseOffset.isScalable())
4978 I =
F.BaseRegs.begin(),
E =
F.BaseRegs.end();
I !=
E; ++
I) {
4984 Immediate::getFixed(NewF.BaseOffset.getFixedValue() +
4985 (
uint64_t)
C->getValue()->getSExtValue());
4986 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
4987 (
I -
F.BaseRegs.begin()));
4988 if (LU.HasFormulaWithSameRegs(NewF)) {
4991 LU.DeleteFormula(
F);
5002 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
5003 (
I -
F.BaseRegs.begin()));
5004 if (LU.HasFormulaWithSameRegs(NewF)) {
5007 LU.DeleteFormula(
F);
5018 LU.RecomputeRegs(LUIdx, RegUses);
5027void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
5028 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5032 dbgs() <<
"The search space is too complex.\n"
5033 "Narrowing the search space by assuming that uses separated "
5034 "by a constant offset will use the same registers.\n");
5038 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5039 LSRUse &LU =
Uses[LUIdx];
5040 for (
const Formula &
F : LU.Formulae) {
5041 if (
F.BaseOffset.isZero() || (
F.Scale != 0 &&
F.Scale != 1))
5043 assert((LU.Kind == LSRUse::Address || LU.Kind == LSRUse::ICmpZero) &&
5044 "Only address and cmp uses expected to have nonzero BaseOffset");
5046 LSRUse *LUThatHas = FindUseWithSimilarFormula(
F, LU);
5050 if (!reconcileNewOffset(*LUThatHas,
F.BaseOffset,
false,
5051 LU.Kind, LU.AccessTy))
5056 LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
5057 LUThatHas->AllFixupsUnconditional &= LU.AllFixupsUnconditional;
5060 for (LSRFixup &
Fixup : LU.Fixups) {
5061 Fixup.Offset +=
F.BaseOffset;
5062 LUThatHas->pushFixup(
Fixup);
5067 Type *FixupType = LUThatHas->Fixups[0].OperandValToReplace->getType();
5068 for (LSRFixup &
Fixup : LUThatHas->Fixups)
5069 assert(
Fixup.OperandValToReplace->getType() == FixupType &&
5070 "Expected all fixups to have the same type");
5075 for (
size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
5076 Formula &
F = LUThatHas->Formulae[i];
5077 if (!
isLegalUse(
TTI, LUThatHas->MinOffset, LUThatHas->MaxOffset,
5078 LUThatHas->Kind, LUThatHas->AccessTy,
F)) {
5080 LUThatHas->DeleteFormula(
F);
5088 LUThatHas->RecomputeRegs(LUThatHas - &
Uses.front(), RegUses);
5091 DeleteUse(LU, LUIdx);
5104void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
5105 if (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5108 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by re-filtering out "
5109 "undesirable dedicated registers.\n");
5111 FilterOutUndesirableDedicatedRegisters();
5126void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
5127 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5131 dbgs() <<
"The search space is too complex.\n"
5132 "Narrowing the search space by choosing the best Formula "
5133 "from the Formulae with the same Scale and ScaledReg.\n");
5136 using BestFormulaeTy = DenseMap<std::pair<const SCEV *, int64_t>,
size_t>;
5138 BestFormulaeTy BestFormulae;
5140 bool ChangedFormulae =
false;
5142 DenseSet<const SCEV *> VisitedRegs;
5143 SmallPtrSet<const SCEV *, 16> Regs;
5145 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5146 LSRUse &LU =
Uses[LUIdx];
5151 auto IsBetterThan = [&](Formula &FA, Formula &FB) {
5156 size_t FARegNum = 0;
5157 for (
const SCEV *
Reg : FA.BaseRegs) {
5158 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5159 FARegNum += (NumUses - UsedByIndices.
count() + 1);
5161 size_t FBRegNum = 0;
5162 for (
const SCEV *
Reg : FB.BaseRegs) {
5163 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(
Reg);
5164 FBRegNum += (NumUses - UsedByIndices.
count() + 1);
5166 if (FARegNum != FBRegNum)
5167 return FARegNum < FBRegNum;
5171 Cost CostFA(Opts, L, SE,
TTI, AMK);
5172 Cost CostFB(Opts, L, SE,
TTI, AMK);
5174 CostFA.RateFormula(FA, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5176 CostFB.RateFormula(FB, Regs, VisitedRegs, LU, HardwareLoopProfitable);
5177 return CostFA.isLess(CostFB);
5181 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5183 Formula &
F = LU.Formulae[FIdx];
5186 auto P = BestFormulae.insert({{
F.ScaledReg,
F.Scale}, FIdx});
5190 Formula &Best = LU.Formulae[
P.first->second];
5191 if (IsBetterThan(
F, Best))
5195 " in favor of formula ";
5196 Best.print(
dbgs());
dbgs() <<
'\n');
5198 ChangedFormulae =
true;
5200 LU.DeleteFormula(
F);
5206 LU.RecomputeRegs(LUIdx, RegUses);
5209 BestFormulae.clear();
5214 "After filtering out undesirable candidates:\n";
5221void LSRInstance::NarrowSearchSpaceByFilterPostInc() {
5224 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5228 "Narrowing the search space by choosing the lowest "
5229 "register Formula for PostInc Uses.\n");
5231 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5232 LSRUse &LU =
Uses[LUIdx];
5234 if (LU.Kind != LSRUse::Address)
5240 size_t MinRegs = std::numeric_limits<size_t>::max();
5241 for (
const Formula &
F : LU.Formulae)
5242 MinRegs = std::min(
F.getNumRegs(), MinRegs);
5245 for (
size_t FIdx = 0, NumForms = LU.Formulae.size(); FIdx != NumForms;
5247 Formula &
F = LU.Formulae[FIdx];
5248 if (
F.getNumRegs() > MinRegs) {
5251 LU.DeleteFormula(
F);
5258 LU.RecomputeRegs(LUIdx, RegUses);
5260 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5267void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
5268 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5272 dbgs() <<
"The search space is too complex.\n"
5273 "Narrowing the search space by merging uses with fixups "
5274 "entirely outside the loop with uses inside the loop.\n");
5276 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5277 LSRUse &LU =
Uses[LUIdx];
5280 if (!LU.AllFixupsOutsideLoop || LU.Formulae.empty() ||
5281 LU.Kind == LSRUse::ICmpZero)
5288 LSRUse *LUToMergeWith =
nullptr;
5289 const Formula &ThisF = LU.Formulae[0];
5290 for (LSRUse &OtherLU :
Uses) {
5292 if (OtherLU.AllFixupsOutsideLoop)
5296 if (OtherLU.Kind == LSRUse::ICmpZero)
5299 if (OtherLU.Formulae.empty())
5302 if (
any_of(OtherLU.Formulae, [&](
const Formula &
F) {
5303 return !isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, OtherLU.Kind,
5304 OtherLU.AccessTy, F);
5311 const Formula &OtherF = OtherLU.Formulae[0];
5312 if (ThisF.BaseRegs == OtherF.BaseRegs &&
5313 ThisF.ScaledReg == OtherF.ScaledReg &&
5314 ThisF.BaseGV == OtherF.BaseGV && ThisF.Scale == OtherF.Scale &&
5315 ThisF.UnfoldedOffset == OtherF.UnfoldedOffset &&
5316 ThisF.BaseOffset == OtherF.BaseOffset) {
5317 LUToMergeWith = &OtherLU;
5328 for (LSRFixup &
Fixup : LU.Fixups) {
5329 LUToMergeWith->pushFixup(
Fixup);
5333 DeleteUse(LU, LUIdx);
5383void LSRInstance::NarrowSearchSpaceByDeletingCostlyFormulas() {
5384 if (EstimateSearchSpaceComplexity() < Opts.lsr_complexity_limit)
5392 SmallPtrSet<const SCEV *, 4> UniqRegs;
5396 DenseMap <const SCEV *, float> RegNumMap;
5397 for (
const SCEV *
Reg : RegUses) {
5401 for (
const LSRUse &LU :
Uses) {
5402 if (!LU.Regs.count(
Reg))
5404 float P = LU.getNotSelectedProbability(
Reg);
5410 RegNumMap.
insert(std::make_pair(
Reg, PNotSel));
5414 dbgs() <<
"Narrowing the search space by deleting costly formulas\n");
5417 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5418 LSRUse &LU =
Uses[LUIdx];
5420 if (LU.Formulae.size() < 2)
5425 float FMinRegNum = LU.Formulae[0].getNumRegs();
5426 float FMinARegNum = LU.Formulae[0].getNumRegs();
5428 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5429 Formula &
F = LU.Formulae[i];
5432 for (
const SCEV *BaseReg :
F.BaseRegs) {
5433 if (UniqRegs.
count(BaseReg))
5435 FRegNum += RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5438 RegNumMap[
BaseReg] / LU.getNotSelectedProbability(BaseReg);
5440 if (
const SCEV *ScaledReg =
F.ScaledReg) {
5441 if (!UniqRegs.
count(ScaledReg)) {
5443 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5446 RegNumMap[ScaledReg] / LU.getNotSelectedProbability(ScaledReg);
5449 if (FMinRegNum > FRegNum ||
5450 (FMinRegNum == FRegNum && FMinARegNum > FARegNum)) {
5451 FMinRegNum = FRegNum;
5452 FMinARegNum = FARegNum;
5457 dbgs() <<
" with min reg num " << FMinRegNum <<
'\n');
5459 std::swap(LU.Formulae[MinIdx], LU.Formulae[0]);
5460 while (LU.Formulae.size() != 1) {
5463 LU.Formulae.pop_back();
5465 LU.RecomputeRegs(LUIdx, RegUses);
5466 assert(LU.Formulae.size() == 1 &&
"Should be exactly 1 min regs formula");
5467 Formula &
F = LU.Formulae[0];
5483 MemAccessTy AccessType) {
5493 return TTI.isLegalAddressingMode(
5494 AccessType.MemTy,
nullptr,
5495 Diff->getSExtValue(),
5496 true, 0, AccessType.AddrSpace) &&
5497 !
TTI.isLegalAddressingMode(
5498 AccessType.MemTy,
nullptr,
5499 -Diff->getSExtValue(),
5500 true, 0, AccessType.AddrSpace);
5506void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
5509 SmallPtrSet<const SCEV *, 4> Taken;
5510 while (EstimateSearchSpaceComplexity() >= Opts.lsr_complexity_limit) {
5517 const SCEV *Best =
nullptr;
5518 unsigned BestNum = 0;
5519 for (
const SCEV *
Reg : RegUses) {
5524 BestNum = RegUses.getUsedByIndices(
Reg).count();
5526 unsigned Count = RegUses.getUsedByIndices(
Reg).count();
5527 if (
Count > BestNum) {
5535 if (
Count == BestNum) {
5536 int LUIdx = RegUses.getUsedByIndices(
Reg).find_first();
5537 if (LUIdx >= 0 &&
Uses[LUIdx].Kind == LSRUse::Address &&
5539 Uses[LUIdx].AccessTy)) {
5546 assert(Best &&
"Failed to find best LSRUse candidate");
5548 LLVM_DEBUG(
dbgs() <<
"Narrowing the search space by assuming " << *Best
5549 <<
" will yield profitable reuse.\n");
5554 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx) {
5555 LSRUse &LU =
Uses[LUIdx];
5556 if (!LU.Regs.count(Best))
continue;
5559 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
5560 Formula &
F = LU.Formulae[i];
5561 if (!
F.referencesReg(Best)) {
5563 LU.DeleteFormula(
F);
5567 assert(e != 0 &&
"Use has no formulae left! Is Regs inconsistent?");
5573 LU.RecomputeRegs(LUIdx, RegUses);
5584void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
5585 NarrowSearchSpaceByDetectingSupersets();
5586 NarrowSearchSpaceByCollapsingUnrolledCode();
5587 NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
5588 if (Opts.lsr_filter_same_scaled_reg)
5589 NarrowSearchSpaceByFilterFormulaWithSameScaledReg();
5590 NarrowSearchSpaceByFilterPostInc();
5591 NarrowSearchSpaceByMergingUsesOutsideLoop();
5592 if (Opts.lsr_exp_narrow)
5593 NarrowSearchSpaceByDeletingCostlyFormulas();
5595 NarrowSearchSpaceByPickingWinnerRegs();
5599void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
5601 SmallVectorImpl<const Formula *> &Workspace,
5602 const Cost &CurCost,
5603 const SmallPtrSet<const SCEV *, 16> &CurRegs,
5604 DenseSet<const SCEV *> &VisitedRegs)
const {
5615 const LSRUse &LU =
Uses[Workspace.
size()];
5621 SmallSetVector<const SCEV *, 4> ReqRegs;
5622 for (
const SCEV *S : CurRegs)
5623 if (LU.Regs.count(S))
5626 SmallPtrSet<const SCEV *, 16> NewRegs;
5627 Cost NewCost(Opts, L, SE,
TTI, AMK);
5628 for (
const Formula &
F : LU.Formulae) {
5636 int NumReqRegsToFind = std::min(
F.getNumRegs(), ReqRegs.
size());
5637 for (
const SCEV *
Reg : ReqRegs) {
5638 if ((
F.ScaledReg &&
F.ScaledReg ==
Reg) ||
5641 if (NumReqRegsToFind == 0)
5645 if (NumReqRegsToFind != 0) {
5656 NewCost.RateFormula(
F, NewRegs, VisitedRegs, LU, HardwareLoopProfitable);
5657 if (NewCost.isLess(SolutionCost)) {
5659 if (Workspace.
size() !=
Uses.size()) {
5660 SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
5661 NewRegs, VisitedRegs);
5662 if (
F.getNumRegs() == 1 && Workspace.
size() == 1)
5663 VisitedRegs.
insert(
F.ScaledReg ?
F.ScaledReg :
F.BaseRegs[0]);
5666 dbgs() <<
".\nRegs:\n";
5667 for (
const SCEV *S : NewRegs)
dbgs()
5668 <<
"- " << *S <<
"\n";
5671 SolutionCost = NewCost;
5672 Solution = Workspace;
5681void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution)
const {
5683 Cost SolutionCost(Opts, L, SE,
TTI, AMK);
5684 SolutionCost.Lose();
5685 Cost CurCost(Opts, L, SE,
TTI, AMK);
5686 SmallPtrSet<const SCEV *, 16> CurRegs;
5687 DenseSet<const SCEV *> VisitedRegs;
5691 SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
5692 CurRegs, VisitedRegs);
5693 if (Solution.
empty()) {
5700 "The chosen solution requires ";
5701 SolutionCost.print(
dbgs());
dbgs() <<
":\n";
5702 for (
size_t i = 0, e =
Uses.size(); i != e; ++i) {
5707 Solution[i]->print(
dbgs());
5713 const bool EnableDropUnprofitableSolution =
valueOr(
5716 if (BaselineCost.isLess(SolutionCost)) {
5717 if (!EnableDropUnprofitableSolution)
5719 dbgs() <<
"Baseline is more profitable than chosen solution, "
5720 "add option 'lsr-drop-solution' to drop LSR solution.\n");
5723 "solution, dropping LSR solution.\n";);
5734 const SmallVectorImpl<Instruction *> &Inputs)
5738 bool AllDominate =
true;
5745 for (Instruction *Inst : Inputs) {
5746 if (Inst == Tentative || !DT.
dominates(Inst, Tentative)) {
5747 AllDominate =
false;
5752 if (Tentative->
getParent() == Inst->getParent() &&
5753 (!BetterPos || !DT.
dominates(Inst, BetterPos)))
5763 const Loop *IPLoop = LI.getLoopFor(IP->getParent());
5764 unsigned IPLoopDepth = IPLoop ? IPLoop->
getLoopDepth() : 0;
5768 if (!Rung)
return IP;
5769 Rung = Rung->getIDom();
5770 if (!Rung)
return IP;
5771 IDom = Rung->getBlock();
5774 const Loop *IDomLoop = LI.getLoopFor(IDom);
5775 unsigned IDomDepth = IDomLoop ? IDomLoop->
getLoopDepth() : 0;
5776 if (IDomDepth <= IPLoopDepth &&
5777 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
5794 SmallVector<Instruction *, 4> Inputs;
5797 if (LU.Kind == LSRUse::ICmpZero)
5798 if (Instruction *
I =
5801 if (LF.PostIncLoops.
count(L)) {
5802 if (LF.isUseFullyOutsideLoop(L))
5803 Inputs.
push_back(
L->getLoopLatch()->getTerminator());
5809 for (
const Loop *PIL : LF.PostIncLoops) {
5810 if (PIL == L)
continue;
5815 if (!ExitingBlocks.
empty()) {
5817 for (
unsigned i = 1, e = ExitingBlocks.
size(); i != e; ++i)
5824 "Insertion point must be a normal instruction");
5834 while (IP->isEHPad()) ++IP;
5839 while (
Rewriter.isInsertedInstruction(&*IP) && IP != LowestIP)
5847Value *LSRInstance::Expand(
const LSRUse &LU,
const LSRFixup &LF,
5849 SmallVectorImpl<WeakTrackingVH> &DeadInsts)
const {
5850 if (LU.RigidFormula)
5851 return LF.OperandValToReplace;
5855 IP = AdjustInsertPositionForExpand(IP, LF, LU);
5860 Rewriter.setPostInc(LF.PostIncLoops);
5865 Type *Ty =
F.getType();
5878 if (LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy()) {
5887 for (
const SCEV *
Reg :
F.BaseRegs) {
5888 assert(!
Reg->isZero() &&
"Zero allocated in a base register!");
5896 Value *ICmpScaledV =
nullptr;
5898 const SCEV *ScaledS =
F.ScaledReg;
5904 if (LU.Kind == LSRUse::ICmpZero) {
5914 "The only scale supported by ICmpZero uses is -1!");
5915 ICmpScaledV =
Rewriter.expandCodeFor(ScaledS,
nullptr);
5923 if (!
Ops.empty() && LU.Kind == LSRUse::Address &&
5933 Ops.push_back(ScaledS);
5959 assert(
F.BaseOffset.isCompatibleImmediate(LF.Offset) &&
5960 "Expanding mismatched offsets\n");
5962 Immediate
Offset =
F.BaseOffset.addUnsigned(LF.Offset);
5963 if (
Offset.isNonZero()) {
5964 if (LU.Kind == LSRUse::ICmpZero) {
5980 Ops.push_back(
Offset.getUnknownSCEV(SE, IntTy));
5985 Immediate UnfoldedOffset =
F.UnfoldedOffset;
5986 if (UnfoldedOffset.isNonZero()) {
5988 Ops.push_back(UnfoldedOffset.getUnknownSCEV(SE, IntTy));
6002 if (LU.Kind == LSRUse::ICmpZero) {
6006 assert(!
F.BaseGV &&
"ICmp does not support folding a global value and "
6007 "a scale at the same time!");
6008 if (
F.Scale == -1) {
6009 if (ICmpScaledV->
getType() != OpTy) {
6019 assert((
F.Scale == 0 ||
F.Scale == 1) &&
6020 "ICmp does not support folding a global value and "
6021 "a scale at the same time!");
6027 if (
C->getType() != OpTy) {
6031 assert(
C &&
"Cast of ConstantInt should have folded");
6044void LSRInstance::RewriteForPHI(PHINode *PN,
const LSRUse &LU,
6045 const LSRFixup &LF,
const Formula &
F,
6046 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6047 DenseMap<BasicBlock *, Value *>
Inserted;
6051 bool needUpdateFixups =
false;
6062 Loop *PNLoop = LI.getLoopFor(Parent);
6063 if (!PNLoop || Parent != PNLoop->
getHeader()) {
6067 CriticalEdgeSplittingOptions SplitOptions(&DT, &LI, MSSAU);
6069 SplitOptions.setMergeIdenticalEdges().setKeepOneInputPHIs();
6070 if (ShouldPreserveLCSSA)
6071 SplitOptions = SplitOptions.setPreserveLCSSA();
6075 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
6077 MSSAU, ShouldPreserveLCSSA);
6087 if (
L->contains(BB) && !
L->contains(PN))
6095 needUpdateFixups =
true;
6100 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> Pair =
6113 LF.OperandValToReplace->
getType(),
"tmp",
6120 if (
L->contains(
I) && !
L->contains(BB))
6121 InsertedNonLCSSAInsts.insert(
I);
6124 Pair.first->second = FullV;
6131 if (needUpdateFixups) {
6132 for (LSRUse &LU :
Uses)
6133 for (LSRFixup &
Fixup : LU.Fixups)
6137 if (
Fixup.UserInst == PN) {
6140 bool foundInOriginalPHI =
false;
6142 if (val ==
Fixup.OperandValToReplace) {
6143 foundInOriginalPHI =
true;
6148 if (foundInOriginalPHI)
6159 if (val ==
Fixup.OperandValToReplace)
6160 Fixup.UserInst = NewPN;
6170void LSRInstance::Rewrite(
const LSRUse &LU,
const LSRFixup &LF,
6172 SmallVectorImpl<WeakTrackingVH> &DeadInsts) {
6176 RewriteForPHI(PN, LU, LF,
F, DeadInsts);
6184 if (FullV->
getType() != OpTy &&
6185 !(LU.Kind == LSRUse::ICmpZero && OpTy->
isPointerTy())) {
6197 if (LU.Kind == LSRUse::ICmpZero)
6213 const LSRFixup &
Fixup,
const LSRUse &LU,
6217 if (LU.Kind != LSRUse::Address)
6218 return IVIncInsertPos;
6222 Type *Ty =
I->getType();
6225 return IVIncInsertPos;
6232 return IVIncInsertPos;
6239void LSRInstance::ImplementSolution(
6240 const SmallVectorImpl<const Formula *> &Solution) {
6246 for (
const IVChain &Chain : IVChainVec) {
6252 for (
size_t LUIdx = 0, NumUses =
Uses.size(); LUIdx != NumUses; ++LUIdx)
6253 for (
const LSRFixup &
Fixup :
Uses[LUIdx].Fixups) {
6256 Rewriter.setIVIncInsertPos(L, InsertPos);
6257 Rewrite(
Uses[LUIdx],
Fixup, *Solution[LUIdx], DeadInsts);
6261 auto InsertedInsts = InsertedNonLCSSAInsts.takeVector();
6264 for (
const IVChain &Chain : IVChainVec) {
6265 GenerateIVChain(Chain, DeadInsts);
6269 for (
const WeakVH &
IV :
Rewriter.getInsertedIVs())
6287 for (PHINode &PN :
L->getHeader()->phis()) {
6288 BinaryOperator *BO =
nullptr;
6294 case Instruction::Sub:
6299 case Instruction::Add:
6316 [&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
6325LSRInstance::LSRInstance(
const ScalarOptions &Opts,
Loop *L, IVUsers &IU,
6326 ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI,
6327 const TargetTransformInfo &
TTI, AssumptionCache &AC,
6328 TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
6330 : Opts(Opts), IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI),
TTI(
TTI),
6331 L(
L), MSSAU(MSSAU), AMK(Opts.lsr_preferred_addressing_mode.value_or(
6332 TTI.getPreferredAddressingMode(
L, &SE))),
6333 Rewriter(SE,
"lsr", PreserveLCSSA), ShouldPreserveLCSSA(PreserveLCSSA),
6334 BaselineCost(Opts,
L, SE,
TTI, AMK) {
6336 if (!
L->isLoopSimplifyForm())
6344 unsigned NumUsers = 0;
6348 LLVM_DEBUG(
dbgs() <<
"LSR skipping loop, too many IV Users in " << U
6356 auto FirstNonPHI = PN->
getParent()->getFirstNonPHIIt();
6366 L->getHeader()->printAsOperand(
dbgs(),
false);
6372 HardwareLoopProfitable =
6373 TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo);
6377#if LLVM_ENABLE_ABI_BREAKING_CHECKS
6380 Rewriter.disableCanonicalMode();
6381 Rewriter.enableLSRMode();
6385 OptimizeLoopTermCond();
6388 if (IU.empty())
return;
6391 if (!
L->isInnermost()) {
6404 CollectInterestingTypesAndFactors();
6405 CollectFixupsAndInitialFormulae();
6406 CollectLoopInvariantFixupsAndFormulae();
6412 print_uses(
dbgs()));
6414 BaselineCost.print(
dbgs());
dbgs() <<
"\n");
6418 GenerateAllReuseFormulae();
6420 FilterOutUndesirableDedicatedRegisters();
6421 NarrowSearchSpaceUsingHeuristics();
6431 if (Solution.
empty())
6436 for (
const LSRUse &LU :
Uses) {
6437 for (
const Formula &
F : LU.Formulae)
6439 F) &&
"Illegal formula generated!");
6444 ImplementSolution(Solution);
6447#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
6448void LSRInstance::print_factors_and_types(
raw_ostream &OS)
const {
6449 if (Factors.empty() &&
Types.empty())
return;
6451 OS <<
"LSR has identified the following interesting factors and types: ";
6454 for (int64_t Factor : Factors)
6455 OS <<
LS <<
'*' << Factor;
6457 for (
Type *Ty : Types)
6458 OS <<
LS <<
'(' << *Ty <<
')';
6462void LSRInstance::print_fixups(raw_ostream &OS)
const {
6463 OS <<
"LSR is examining the following fixup sites:\n";
6464 for (
const LSRUse &LU :
Uses)
6465 for (
const LSRFixup &LF : LU.Fixups) {
6472void LSRInstance::print_uses(raw_ostream &OS)
const {
6473 OS <<
"LSR is examining the following uses:\n";
6474 for (
const LSRUse &LU :
Uses) {
6478 for (
const Formula &
F : LU.Formulae) {
6486void LSRInstance::print(raw_ostream &OS)
const {
6487 print_factors_and_types(OS);
6499class LoopStrengthReduce :
public LoopPass {
6503 LoopStrengthReduce();
6506 bool runOnLoop(
Loop *L, LPPassManager &LPM)
override;
6507 void getAnalysisUsage(AnalysisUsage &AU)
const override;
6512LoopStrengthReduce::LoopStrengthReduce() : LoopPass(
ID) {
6516void LoopStrengthReduce::getAnalysisUsage(
AnalysisUsage &AU)
const {
6543ToDwarfOpIter(SmallVectorImpl<uint64_t> &Expr) {
6544 llvm::DIExpression::expr_op_iterator Begin =
6545 llvm::DIExpression::expr_op_iterator(Expr.
begin());
6546 llvm::DIExpression::expr_op_iterator
End =
6547 llvm::DIExpression::expr_op_iterator(Expr.
end());
6548 return {Begin,
End};
6551struct SCEVDbgValueBuilder {
6552 SCEVDbgValueBuilder() =
default;
6553 SCEVDbgValueBuilder(
const SCEVDbgValueBuilder &
Base) { clone(
Base); }
6555 void clone(
const SCEVDbgValueBuilder &
Base) {
6556 LocationOps =
Base.LocationOps;
6561 LocationOps.
clear();
6568 SmallVector<Value *, 2> LocationOps;
6578 unsigned ArgIndex = 0;
6579 if (It != LocationOps.
end()) {
6580 ArgIndex = std::distance(LocationOps.
begin(), It);
6582 ArgIndex = LocationOps.
size();
6588 void pushValue(
const SCEVUnknown *U) {
6593 bool pushConst(
const SCEVConstant *
C) {
6594 if (
C->getAPInt().getSignificantBits() > 64)
6596 Expr.
push_back(llvm::dwarf::DW_OP_consts);
6597 Expr.
push_back(
C->getAPInt().getSExtValue());
6604 return ToDwarfOpIter(Expr);
6609 bool pushArithmeticExpr(
const llvm::SCEVCommutativeExpr *CommExpr,
6612 "Expected arithmetic SCEV type");
6614 unsigned EmitOperator = 0;
6615 for (
const auto &
Op : CommExpr->
operands()) {
6618 if (EmitOperator >= 1)
6619 pushOperator(DwarfOp);
6626 bool pushCast(
const llvm::SCEVCastExpr *
C,
bool IsSigned) {
6627 const llvm::SCEV *Inner =
C->getOperand(0);
6628 const llvm::Type *
Type =
C->getType();
6630 bool Success = pushSCEV(Inner);
6632 IsSigned ? llvm::dwarf::DW_ATE_signed
6633 : llvm::dwarf::DW_ATE_unsigned};
6634 for (
const auto &
Op : CastOps)
6640 bool pushSCEV(
const llvm::SCEV *S) {
6643 Success &= pushConst(StartInt);
6648 pushLocation(
U->getValue());
6651 Success &= pushArithmeticExpr(MulRec, llvm::dwarf::DW_OP_mul);
6654 Success &= pushSCEV(UDiv->getLHS());
6655 Success &= pushSCEV(UDiv->getRHS());
6656 pushOperator(llvm::dwarf::DW_OP_div);
6662 "Unexpected cast type in SCEV.");
6666 Success &= pushArithmeticExpr(AddExpr, llvm::dwarf::DW_OP_plus);
6681 bool isIdentityFunction(
uint64_t Op,
const SCEV *S) {
6683 if (
C->getAPInt().getSignificantBits() > 64)
6685 int64_t
I =
C->getAPInt().getSExtValue();
6687 case llvm::dwarf::DW_OP_plus:
6688 case llvm::dwarf::DW_OP_minus:
6690 case llvm::dwarf::DW_OP_mul:
6691 case llvm::dwarf::DW_OP_div:
6704 bool SCEVToValueExpr(
const llvm::SCEVAddRecExpr &SAR, ScalarEvolution &SE) {
6710 if (!isIdentityFunction(llvm::dwarf::DW_OP_mul, Stride)) {
6711 if (!pushSCEV(Stride))
6713 pushOperator(llvm::dwarf::DW_OP_mul);
6715 if (!isIdentityFunction(llvm::dwarf::DW_OP_plus, Start)) {
6716 if (!pushSCEV(Start))
6718 pushOperator(llvm::dwarf::DW_OP_plus);
6724 void createOffsetExpr(int64_t
Offset,
Value *OffsetValue) {
6725 pushLocation(OffsetValue);
6728 dbgs() <<
"scev-salvage: Generated IV offset expression. Offset: "
6729 << std::to_string(
Offset) <<
"\n");
6735 bool createIterCountExpr(
const SCEV *S,
6736 const SCEVDbgValueBuilder &IterationCount,
6737 ScalarEvolution &SE) {
6746 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Location to salvage SCEV: " << *S
6750 if (!Rec->isAffine())
6758 clone(IterationCount);
6759 if (!SCEVToValueExpr(*Rec, SE))
6770 bool SCEVToIterCountExpr(
const llvm::SCEVAddRecExpr &SAR,
6771 ScalarEvolution &SE) {
6777 if (!isIdentityFunction(llvm::dwarf::DW_OP_minus, Start)) {
6778 if (!pushSCEV(Start))
6780 pushOperator(llvm::dwarf::DW_OP_minus);
6782 if (!isIdentityFunction(llvm::dwarf::DW_OP_div, Stride)) {
6783 if (!pushSCEV(Stride))
6785 pushOperator(llvm::dwarf::DW_OP_div);
6793 void appendToVectors(SmallVectorImpl<uint64_t> &DestExpr,
6794 SmallVectorImpl<Value *> &DestLocations) {
6796 "Expected the locations vector to contain the IV");
6801 "Expected the location ops to contain the IV.");
6805 for (
const auto &
Op : LocationOps) {
6806 auto It =
find(DestLocations,
Op);
6807 if (It != DestLocations.
end()) {
6809 DestIndexMap.
push_back(std::distance(DestLocations.
begin(), It));
6817 for (
const auto &
Op : expr_ops()) {
6820 Op.appendToVector(DestExpr);
6827 uint64_t NewIndex = DestIndexMap[Arg.getIndex()];
6835struct DVIRecoveryRec {
6836 DVIRecoveryRec(DbgVariableRecord *DVR)
6837 : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(
false) {}
6839 DbgVariableRecord *DbgRef;
6841 bool HadLocationArgList;
6847 for (
auto &RE : RecoveryExprs)
6849 RecoveryExprs.clear();
6852 ~DVIRecoveryRec() { clear(); }
6860 auto expr_ops = ToDwarfOpIter(Expr);
6862 for (
auto Op : expr_ops)
6871template <
typename T>
6875 "contain any DW_OP_llvm_arg operands.");
6881template <
typename T>
6886 "Expected expression that references DIArglist locations using "
6887 "DW_OP_llvm_arg operands.");
6889 for (
Value *V : Locations)
6906 if (NumLLVMArgs == 0) {
6913 "Lone LLVM_arg in a DIExpression should refer to location-op 0.");
6943 LLVM_DEBUG(
dbgs() <<
"scev-salvage: restore dbg.value to pre-LSR state\n"
6944 <<
"scev-salvage: post-LSR: " << *DbgVal <<
'\n');
6945 assert(DVIRec.Expr &&
"Expected an expression");
6950 if (!DVIRec.HadLocationArgList) {
6951 assert(DVIRec.LocationOps.size() == 1 &&
6952 "Unexpected number of location ops.");
6956 Value *CachedValue =
6961 for (
WeakVH VH : DVIRec.LocationOps) {
6969 LLVM_DEBUG(
dbgs() <<
"scev-salvage: pre-LSR: " << *DbgVal <<
'\n');
6974 const SCEV *SCEVInductionVar,
6975 SCEVDbgValueBuilder IterCountExpr) {
6989 LocationOpIndexMap.
assign(DVIRec.LocationOps.size(), -1);
6991 NewLocationOps.
push_back(LSRInductionVar);
6993 for (
unsigned i = 0; i < DVIRec.LocationOps.size(); i++) {
6994 WeakVH VH = DVIRec.LocationOps[i];
7000 LocationOpIndexMap[i] = NewLocationOps.
size() - 1;
7002 <<
" now at index " << LocationOpIndexMap[i] <<
"\n");
7010 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV for location at index: " << i
7011 <<
" refers to a location that is now undef or erased. "
7012 "Salvage abandoned.\n");
7016 LLVM_DEBUG(
dbgs() <<
"scev-salvage: salvaging location at index " << i
7017 <<
" with SCEV: " << *DVIRec.SCEVs[i] <<
"\n");
7019 DVIRec.RecoveryExprs[i] = std::make_unique<SCEVDbgValueBuilder>();
7020 SCEVDbgValueBuilder *SalvageExpr = DVIRec.RecoveryExprs[i].get();
7024 if (std::optional<APInt>
Offset =
7026 if (
Offset->getSignificantBits() <= 64)
7027 SalvageExpr->createOffsetExpr(
Offset->getSExtValue(), LSRInductionVar);
7030 }
else if (!SalvageExpr->createIterCountExpr(DVIRec.SCEVs[i], IterCountExpr,
7039 assert(DVIRec.RecoveryExprs.size() == 1 &&
7040 "Expected only a single recovery expression for an empty "
7042 assert(DVIRec.RecoveryExprs[0] &&
7043 "Expected a SCEVDbgSalvageBuilder for location 0");
7044 SCEVDbgValueBuilder *
B = DVIRec.RecoveryExprs[0].get();
7045 B->appendToVectors(
NewExpr, NewLocationOps);
7047 for (
const auto &
Op : DVIRec.Expr->
expr_ops()) {
7055 uint64_t LocationArgIndex = Arg.getIndex();
7056 SCEVDbgValueBuilder *DbgBuilder =
7057 DVIRec.RecoveryExprs[LocationArgIndex].get();
7063 assert(LocationOpIndexMap[LocationArgIndex] != -1 &&
7064 "Expected a positive index for the location-op position.");
7065 NewExpr.push_back(LocationOpIndexMap[LocationArgIndex]);
7069 DbgBuilder->appendToVectors(
NewExpr, NewLocationOps);
7073 LLVM_DEBUG(
dbgs() <<
"scev-salvage: Updated DVI: " << *DVIRec.DbgRef <<
"\n");
7081 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &DVIToUpdate) {
7082 if (DVIToUpdate.empty())
7086 assert(SCEVInductionVar &&
7087 "Anticipated a SCEV for the post-LSR induction variable");
7091 if (!IVAddRec->isAffine())
7099 SCEVDbgValueBuilder IterCountExpr;
7100 IterCountExpr.pushLocation(LSRInductionVar);
7101 if (!IterCountExpr.SCEVToIterCountExpr(*IVAddRec, SE))
7104 LLVM_DEBUG(
dbgs() <<
"scev-salvage: IV SCEV: " << *SCEVInductionVar
7107 for (
auto &DVIRec : DVIToUpdate) {
7108 SalvageDVI(L, SE, LSRInductionVar, *DVIRec, SCEVInductionVar,
7119 SmallVector<std::unique_ptr<DVIRecoveryRec>, 2> &SalvageableDVISCEVs) {
7120 for (
const auto &
B : L->getBlocks()) {
7121 for (
auto &
I : *
B) {
7123 if (!DbgVal.isDbgValue() && !DbgVal.isDbgAssign())
7128 if (DbgVal.isKillLocation())
7133 const auto &HasTranslatableLocationOps =
7135 for (
const auto LocOp : DbgValToTranslate.location_ops()) {
7149 if (!HasTranslatableLocationOps(DbgVal))
7152 std::unique_ptr<DVIRecoveryRec> NewRec =
7153 std::make_unique<DVIRecoveryRec>(&DbgVal);
7157 NewRec->RecoveryExprs.resize(DbgVal.getNumVariableLocationOps());
7158 for (
const auto LocOp : DbgVal.location_ops()) {
7159 NewRec->SCEVs.push_back(SE.
getSCEV(LocOp));
7160 NewRec->LocationOps.push_back(LocOp);
7161 NewRec->HadLocationArgList = DbgVal.hasArgList();
7163 SalvageableDVISCEVs.push_back(std::move(NewRec));
7173 const LSRInstance &LSR) {
7175 auto IsSuitableIV = [&](
PHINode *
P) {
7186 for (
const WeakVH &
IV : LSR.getScalarEvolutionIVs()) {
7193 if (IsSuitableIV(
P))
7197 for (
PHINode &
P : L.getHeader()->phis()) {
7198 if (IsSuitableIV(&
P))
7217 std::unique_ptr<MemorySSAUpdater> MSSAU;
7219 MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
7222 const LSRInstance &Reducer = LSRInstance(Opts, L, IU, SE, DT, LI,
TTI, AC,
7223 TLI, MSSAU.get(), PreserveLCSSA);
7224 Changed |= Reducer.getChanged();
7228 if (Opts.enable_lsr_phielim && L->isLoopSimplifyForm()) {
7231#if LLVM_ENABLE_ABI_BREAKING_CHECKS
7234 unsigned numFolded = Rewriter.replaceCongruentIVs(L, &DT, DeadInsts, &
TTI);
7248 if (L->isRecursivelyLCSSAForm(DT, LI) && L->getExitBlock()) {
7262 if (SalvageableDVIRecords.
empty())
7268 for (
const auto &L : LI) {
7272 LLVM_DEBUG(
dbgs() <<
"scev-salvage: SCEV salvaging not possible. An IV "
7273 "could not be identified.\n");
7277 for (
auto &Rec : SalvageableDVIRecords)
7279 SalvageableDVIRecords.
clear();
7283bool LoopStrengthReduce::runOnLoop(
Loop *L, LPPassManager & ) {
7287 auto &IU = getAnalysis<IVUsersWrapperPass>().getIU();
7288 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
7289 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7290 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
7291 const auto &
TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
7292 *
L->getHeader()->getParent());
7293 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
7294 *
L->getHeader()->getParent());
7295 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
7296 *
L->getHeader()->getParent());
7297 auto *MSSAAnalysis = getAnalysisIfAvailable<MemorySSAWrapperPass>();
7300 MSSA = &MSSAAnalysis->getMSSA();
7319char LoopStrengthReduce::ID = 0;
7322 "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.
SmallVector< MachineOperand, 4 > 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 isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isNegative() const
Determine sign of this APInt.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
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.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
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.
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
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 * getExitCount(const Loop *L, const BasicBlock *ExitingBlock, ExitCountKind Kind=Exact)
Return the number of times the backedge executes before the given exit would be taken; if not exactly...
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...
APInt getUnsignedRangeMax(const SCEV *S)
Determine the max of the unsigned range for a particular SCEV.
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.
const ScalarOptions & getScalarOptions(const LLVMContext &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