56 #define DEBUG_TYPE "loop-reduce"
93 cl::desc(
"Enable LSR phi elimination"));
99 cl::desc(
"Stress test LSR IV chains"));
122 OS <<
"[NumUses=" << UsedByIndices.count() <<
']';
125 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
135 class RegUseTracker {
138 RegUsesTy RegUsesMap;
142 void CountRegister(
const SCEV *
Reg,
size_t LUIdx);
143 void DropRegister(
const SCEV *
Reg,
size_t LUIdx);
144 void SwapAndDropUse(
size_t LUIdx,
size_t LastLUIdx);
146 bool isRegUsedByUsesOtherThan(
const SCEV *
Reg,
size_t LUIdx)
const;
154 iterator
begin() {
return RegSequence.
begin(); }
155 iterator
end() {
return RegSequence.
end(); }
156 const_iterator
begin()
const {
return RegSequence.
begin(); }
157 const_iterator
end()
const {
return RegSequence.
end(); }
163 RegUseTracker::CountRegister(
const SCEV *
Reg,
size_t LUIdx) {
164 std::pair<RegUsesTy::iterator, bool> Pair =
165 RegUsesMap.insert(std::make_pair(Reg, RegSortData()));
166 RegSortData &RSD = Pair.first->second;
168 RegSequence.push_back(Reg);
169 RSD.UsedByIndices.resize(std::max(RSD.UsedByIndices.size(), LUIdx + 1));
170 RSD.UsedByIndices.set(LUIdx);
174 RegUseTracker::DropRegister(
const SCEV *Reg,
size_t LUIdx) {
175 RegUsesTy::iterator It = RegUsesMap.find(Reg);
176 assert(It != RegUsesMap.end());
177 RegSortData &RSD = It->second;
178 assert(RSD.UsedByIndices.size() > LUIdx);
179 RSD.UsedByIndices.reset(LUIdx);
183 RegUseTracker::SwapAndDropUse(
size_t LUIdx,
size_t LastLUIdx) {
184 assert(LUIdx <= LastLUIdx);
188 for (RegUsesTy::iterator
I = RegUsesMap.begin(), E = RegUsesMap.end();
191 if (LUIdx < UsedByIndices.
size())
192 UsedByIndices[LUIdx] =
193 LastLUIdx < UsedByIndices.
size() ? UsedByIndices[LastLUIdx] : 0;
194 UsedByIndices.
resize(std::min(UsedByIndices.
size(), LastLUIdx));
199 RegUseTracker::isRegUsedByUsesOtherThan(
const SCEV *Reg,
size_t LUIdx)
const {
200 RegUsesTy::const_iterator
I = RegUsesMap.find(Reg);
201 if (I == RegUsesMap.end())
205 if (i == -1)
return false;
206 if ((
size_t)i != LUIdx)
return true;
211 RegUsesTy::const_iterator I = RegUsesMap.find(Reg);
212 assert(I != RegUsesMap.end() &&
"Unknown register!");
213 return I->second.UsedByIndices;
216 void RegUseTracker::clear() {
245 const SCEV *ScaledReg;
250 int64_t UnfoldedOffset;
253 : BaseGV(0), BaseOffset(0), HasBaseReg(
false), Scale(0), ScaledReg(0),
258 unsigned getNumRegs()
const;
261 void DeleteBaseReg(
const SCEV *&S);
263 bool referencesReg(
const SCEV *S)
const;
264 bool hasRegsUsedByUsesOtherThan(
size_t LUIdx,
265 const RegUseTracker &RegUses)
const;
285 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
294 if (!AR->getStart()->isZero()) {
297 AR->getStepRecurrence(SE),
305 if (
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S))
306 if (Mul->getOperand(0)->isAllOnesValue()) {
316 E = MyGood.
end(); I != E; ++
I)
319 E = MyBad.
end(); I != E; ++
I)
339 BaseRegs.push_back(Sum);
345 BaseRegs.push_back(Sum);
353 unsigned Formula::getNumRegs()
const {
354 return !!ScaledReg + BaseRegs.size();
360 return !BaseRegs.empty() ? BaseRegs.front()->getType() :
361 ScaledReg ? ScaledReg->getType() :
362 BaseGV ? BaseGV->getType() :
367 void Formula::DeleteBaseReg(
const SCEV *&S) {
368 if (&S != &BaseRegs.back())
374 bool Formula::referencesReg(
const SCEV *S)
const {
375 return S == ScaledReg ||
376 std::find(BaseRegs.begin(), BaseRegs.end(), S) != BaseRegs.end();
381 bool Formula::hasRegsUsedByUsesOtherThan(
size_t LUIdx,
382 const RegUseTracker &RegUses)
const {
384 if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
387 E = BaseRegs.end(); I != E; ++
I)
388 if (RegUses.isRegUsedByUsesOtherThan(*I, LUIdx))
396 if (!First) OS <<
" + ";
else First =
false;
399 if (BaseOffset != 0) {
400 if (!First) OS <<
" + ";
else First =
false;
404 E = BaseRegs.end(); I != E; ++
I) {
405 if (!First) OS <<
" + ";
else First =
false;
406 OS <<
"reg(" << **I <<
')';
408 if (HasBaseReg && BaseRegs.empty()) {
409 if (!First) OS <<
" + ";
else First =
false;
410 OS <<
"**error: HasBaseReg**";
411 }
else if (!HasBaseReg && !BaseRegs.empty()) {
412 if (!First) OS <<
" + ";
else First =
false;
413 OS <<
"**error: !HasBaseReg**";
416 if (!First) OS <<
" + ";
else First =
false;
417 OS << Scale <<
"*reg(";
424 if (UnfoldedOffset != 0) {
425 if (!First) OS <<
" + ";
else First =
false;
426 OS <<
"imm(" << UnfoldedOffset <<
')';
430 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
469 bool IgnoreSignificantBits =
false) {
491 const APInt &LA =
C->getValue()->getValue();
493 if (LA.
srem(RA) != 0)
502 IgnoreSignificantBits);
505 IgnoreSignificantBits);
506 if (!Start)
return 0;
516 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(LHS)) {
522 IgnoreSignificantBits);
532 if (
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(LHS)) {
541 IgnoreSignificantBits)) {
561 if (
C->getValue()->getValue().getMinSignedBits() <= 64) {
563 return C->getValue()->getSExtValue();
565 }
else if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
571 }
else if (
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
587 if (
const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
588 if (
GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue())) {
592 }
else if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
598 }
else if (
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
613 bool isAddress = isa<LoadInst>(Inst);
614 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
615 if (SI->getOperand(1) == OperandVal)
617 }
else if (
IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
620 switch (II->getIntrinsicID()) {
627 if (II->getArgOperand(0) == OperandVal)
638 if (
const StoreInst *SI = dyn_cast<StoreInst>(Inst))
639 AccessTy = SI->getOperand(0)->getType();
640 else if (
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
643 switch (II->getIntrinsicID()) {
649 AccessTy = II->getArgOperand(0)->getType();
656 if (
PointerType *PTy = dyn_cast<PointerType>(AccessTy))
658 PTy->getAddressSpace());
707 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
716 if (
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
717 if (Mul->getNumOperands() == 2) {
719 if (isa<SCEVConstant>(Mul->getOperand(0)))
724 if (
const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Mul->getOperand(1))) {
725 Value *UVal = U->getValue();
730 if (User && User->
getOpcode() == Instruction::Mul
732 return SE.
getSCEV(User) == Mul;
753 bool Changed =
false;
755 while (!DeadInsts.
empty()) {
784 const LSRUse &LU,
const Formula &
F);
795 unsigned NumBaseAdds;
802 : NumRegs(0), AddRecCost(0), NumIVMuls(0), NumBaseAdds(0), ImmCost(0),
803 SetupCost(0), ScaleCost(0) {}
812 return ((NumRegs | AddRecCost | NumIVMuls | NumBaseAdds
813 | ImmCost | SetupCost | ScaleCost) != ~0u)
814 || ((NumRegs & AddRecCost & NumIVMuls & NumBaseAdds
815 & ImmCost & SetupCost & ScaleCost) == ~0u);
820 assert(isValid() &&
"invalid cost");
821 return NumRegs == ~0u;
838 void RateRegister(
const SCEV *Reg,
842 void RatePrimaryRegister(
const SCEV *Reg,
852 void Cost::RateRegister(
const SCEV *Reg,
861 if (AR->getLoop() != L) {
874 if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1))) {
875 if (!Regs.
count(AR->getOperand(1))) {
876 RateRegister(AR->getOperand(1), Regs, L, SE, DT);
886 if (!isa<SCEVUnknown>(Reg) &&
887 !isa<SCEVConstant>(
Reg) &&
888 !(isa<SCEVAddRecExpr>(Reg) &&
889 (isa<SCEVUnknown>(cast<SCEVAddRecExpr>(
Reg)->getStart()) ||
890 isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart()))))
893 NumIVMuls += isa<SCEVMulExpr>(
Reg) &&
900 void Cost::RatePrimaryRegister(
const SCEV *Reg,
905 if (LoserRegs && LoserRegs->
count(Reg)) {
910 RateRegister(Reg, Regs, L, SE, DT);
911 if (LoserRegs && isLoser())
926 if (
const SCEV *ScaledReg = F.ScaledReg) {
927 if (VisitedRegs.
count(ScaledReg)) {
931 RatePrimaryRegister(ScaledReg, Regs, L, SE, DT, LoserRegs);
936 E = F.BaseRegs.end(); I != E; ++
I) {
937 const SCEV *BaseReg = *
I;
938 if (VisitedRegs.
count(BaseReg)) {
942 RatePrimaryRegister(BaseReg, Regs, L, SE, DT, LoserRegs);
948 size_t NumBaseParts = F.BaseRegs.size() + (F.UnfoldedOffset != 0);
949 if (NumBaseParts > 1)
959 E = Offsets.
end(); I != E; ++
I) {
960 int64_t Offset = (uint64_t)*I + F.BaseOffset;
964 else if (Offset != 0)
967 assert(isValid() &&
"invalid cost");
983 if (NumRegs != Other.NumRegs)
984 return NumRegs < Other.NumRegs;
985 if (AddRecCost != Other.AddRecCost)
986 return AddRecCost < Other.AddRecCost;
987 if (NumIVMuls != Other.NumIVMuls)
988 return NumIVMuls < Other.NumIVMuls;
989 if (NumBaseAdds != Other.NumBaseAdds)
990 return NumBaseAdds < Other.NumBaseAdds;
991 if (ScaleCost != Other.ScaleCost)
992 return ScaleCost < Other.ScaleCost;
993 if (ImmCost != Other.ImmCost)
994 return ImmCost < Other.ImmCost;
995 if (SetupCost != Other.SetupCost)
996 return SetupCost < Other.SetupCost;
1001 OS << NumRegs <<
" reg" << (NumRegs == 1 ?
"" :
"s");
1002 if (AddRecCost != 0)
1003 OS <<
", with addrec cost " << AddRecCost;
1005 OS <<
", plus " << NumIVMuls <<
" IV mul" << (NumIVMuls == 1 ?
"" :
"s");
1006 if (NumBaseAdds != 0)
1007 OS <<
", plus " << NumBaseAdds <<
" base add"
1008 << (NumBaseAdds == 1 ?
"" :
"s");
1010 OS <<
", plus " << ScaleCost <<
" scale cost";
1012 OS <<
", plus " << ImmCost <<
" imm cost";
1014 OS <<
", plus " << SetupCost <<
" setup cost";
1017 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1034 Value *OperandValToReplace;
1050 bool isUseFullyOutsideLoop(
const Loop *L)
const;
1060 LSRFixup::LSRFixup()
1061 : UserInst(0), OperandValToReplace(0), LUIdx(~size_t(0)), Offset(0) {}
1065 bool LSRFixup::isUseFullyOutsideLoop(
const Loop *L)
const {
1067 if (
const PHINode *PN = dyn_cast<PHINode>(UserInst)) {
1068 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1069 if (PN->getIncomingValue(i) == OperandValToReplace &&
1070 L->
contains(PN->getIncomingBlock(i)))
1084 }
else if (UserInst->getType()->isVoidTy())
1085 OS << UserInst->getOpcodeName();
1089 OS <<
", OperandValToReplace=";
1093 E = PostIncLoops.end(); I != E; ++
I) {
1094 OS <<
", PostIncLoop=";
1098 if (LUIdx != ~
size_t(0))
1099 OS <<
", LUIdx=" << LUIdx;
1102 OS <<
", Offset=" << Offset;
1105 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1115 struct UniquifierDenseMapInfo {
1118 V.
push_back(reinterpret_cast<const SCEV *>(-1));
1124 V.
push_back(reinterpret_cast<const SCEV *>(-2));
1129 unsigned Result = 0;
1131 E = V.
end(); I != E; ++
I)
1171 bool AllFixupsOutsideLoop;
1184 Type *WidestFixupType;
1194 LSRUse(KindType K,
Type *
T) :
Kind(K), AccessTy(T),
1195 MinOffset(INT64_MAX),
1197 AllFixupsOutsideLoop(
true),
1198 RigidFormula(
false),
1199 WidestFixupType(0) {}
1201 bool HasFormulaWithSameRegs(
const Formula &F)
const;
1202 bool InsertFormula(
const Formula &F);
1203 void DeleteFormula(Formula &F);
1204 void RecomputeRegs(
size_t LUIdx, RegUseTracker &Reguses);
1214 bool LSRUse::HasFormulaWithSameRegs(
const Formula &F)
const {
1216 if (F.ScaledReg) Key.
push_back(F.ScaledReg);
1219 return Uniquifier.count(Key);
1224 bool LSRUse::InsertFormula(
const Formula &F) {
1225 if (!Formulae.empty() && RigidFormula)
1229 if (F.ScaledReg) Key.
push_back(F.ScaledReg);
1233 if (!Uniquifier.insert(Key).second)
1237 assert((!F.ScaledReg || !F.ScaledReg->isZero()) &&
1238 "Zero allocated in a scaled register!");
1241 F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++
I)
1242 assert(!(*I)->isZero() &&
"Zero allocated in a base register!");
1246 Formulae.push_back(F);
1249 Regs.
insert(F.BaseRegs.begin(), F.BaseRegs.end());
1255 void LSRUse::DeleteFormula(Formula &F) {
1256 if (&F != &Formulae.back())
1258 Formulae.pop_back();
1262 void LSRUse::RecomputeRegs(
size_t LUIdx, RegUseTracker &RegUses) {
1267 E = Formulae.end(); I != E; ++
I) {
1268 const Formula &F = *
I;
1269 if (F.ScaledReg) Regs.
insert(F.ScaledReg);
1270 Regs.
insert(F.BaseRegs.begin(), F.BaseRegs.end());
1275 E = OldRegs.
end(); I != E; ++
I)
1276 if (!Regs.
count(*I))
1277 RegUses.DropRegister(*I, LUIdx);
1281 OS <<
"LSR Use: Kind=";
1283 case Basic: OS <<
"Basic";
break;
1284 case Special: OS <<
"Special";
break;
1285 case ICmpZero: OS <<
"ICmpZero";
break;
1287 OS <<
"Address of ";
1288 if (AccessTy->isPointerTy())
1294 OS <<
", Offsets={";
1296 E = Offsets.
end(); I != E; ++
I) {
1303 if (AllFixupsOutsideLoop)
1304 OS <<
", all-fixups-outside-loop";
1306 if (WidestFixupType)
1307 OS <<
", widest fixup type: " << *WidestFixupType;
1310 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1321 bool HasBaseReg, int64_t Scale) {
1323 case LSRUse::Address:
1329 case LSRUse::ICmpZero:
1336 if (Scale != 0 && HasBaseReg && BaseOffset != 0)
1341 if (Scale != 0 && Scale != -1)
1346 if (BaseOffset != 0) {
1353 BaseOffset = -(uint64_t)BaseOffset;
1362 return !BaseGV && Scale == 0 && BaseOffset == 0;
1364 case LSRUse::Special:
1366 return !BaseGV && (Scale == 0 || Scale == -1) && BaseOffset == 0;
1374 GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg,
1377 if (((int64_t)((uint64_t)BaseOffset + MinOffset) > BaseOffset) !=
1380 MinOffset = (uint64_t)BaseOffset + MinOffset;
1381 if (((int64_t)((uint64_t)BaseOffset + MaxOffset) > BaseOffset) !=
1384 MaxOffset = (uint64_t)BaseOffset + MaxOffset;
1386 return isLegalUse(TTI, Kind, AccessTy, BaseGV, MinOffset, HasBaseReg,
1388 isLegalUse(TTI, Kind, AccessTy, BaseGV, MaxOffset, HasBaseReg, Scale);
1394 return isLegalUse(TTI, MinOffset, MaxOffset, Kind, AccessTy, F.BaseGV,
1395 F.BaseOffset, F.HasBaseReg, F.Scale);
1407 if (LU.Kind != LSRUse::Address)
1415 if (F.BaseRegs.size() < 2)
1418 return isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
1419 F.BaseGV, F.BaseOffset, F.HasBaseReg, 1);
1423 const LSRUse &LU,
const Formula &F) {
1426 assert(
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind,
1427 LU.AccessTy, F) &&
"Illegal formula in use.");
1430 case LSRUse::Address: {
1432 int ScaleCostMinOffset =
1434 F.BaseOffset + LU.MinOffset,
1435 F.HasBaseReg, F.Scale);
1436 int ScaleCostMaxOffset =
1438 F.BaseOffset + LU.MaxOffset,
1439 F.HasBaseReg, F.Scale);
1441 assert(ScaleCostMinOffset >= 0 && ScaleCostMaxOffset >= 0 &&
1442 "Legal addressing mode has an illegal cost!");
1443 return std::max(ScaleCostMinOffset, ScaleCostMaxOffset);
1445 case LSRUse::ICmpZero:
1448 return F.Scale != -1;
1451 case LSRUse::Special:
1459 LSRUse::KindType
Kind,
Type *AccessTy,
1463 if (BaseOffset == 0 && !BaseGV)
return true;
1467 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
1471 if (!HasBaseReg && Scale == 1) {
1476 return isLegalUse(TTI, Kind, AccessTy, BaseGV, BaseOffset, HasBaseReg, Scale);
1482 Type *AccessTy,
const SCEV *S,
bool HasBaseReg) {
1484 if (S->
isZero())
return true;
1492 if (!S->
isZero())
return false;
1495 if (BaseOffset == 0 && !BaseGV)
return true;
1499 int64_t Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
1501 return isLegalUse(TTI, MinOffset, MaxOffset, Kind, AccessTy, BaseGV,
1502 BaseOffset, HasBaseReg, Scale);
1509 struct UseMapDenseMapInfo {
1510 static std::pair<const SCEV *, LSRUse::KindType> getEmptyKey() {
1511 return std::make_pair(reinterpret_cast<const SCEV *>(-1), LSRUse::Basic);
1514 static std::pair<const SCEV *, LSRUse::KindType> getTombstoneKey() {
1515 return std::make_pair(reinterpret_cast<const SCEV *>(-2), LSRUse::Basic);
1519 getHashValue(
const std::pair<const SCEV *, LSRUse::KindType> &V) {
1525 static bool isEqual(
const std::pair<const SCEV *, LSRUse::KindType> &LHS,
1526 const std::pair<const SCEV *, LSRUse::KindType> &RHS) {
1543 const SCEV *IncExpr;
1546 UserInst(U), IVOperand(O), IncExpr(E) {}
1553 const SCEV *ExprBase;
1555 IVChain() : ExprBase(0) {}
1557 IVChain(
const IVInc &Head,
const SCEV *Base)
1558 : Incs(1, Head), ExprBase(Base) {}
1563 const_iterator
begin()
const {
1564 assert(!Incs.empty());
1567 const_iterator
end()
const {
1572 bool hasIncs()
const {
return Incs.size() >= 2; }
1575 void add(
const IVInc &
X) { Incs.push_back(X); }
1578 Instruction *tailUserInst()
const {
return Incs.back().UserInst; }
1582 bool isProfitableIncrement(
const SCEV *OperExpr,
1583 const SCEV *IncExpr,
1625 RegUseTracker RegUses;
1630 static const unsigned MaxChains = 8;
1638 void OptimizeShadowIV();
1641 void OptimizeLoopTermCond();
1645 void FinalizeChain(IVChain &Chain);
1646 void CollectChains();
1650 void CollectInterestingTypesAndFactors();
1651 void CollectFixupsAndInitialFormulae();
1653 LSRFixup &getNewFixup() {
1654 Fixups.push_back(LSRFixup());
1661 UseMapDenseMapInfo> UseMapTy;
1664 bool reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
bool HasBaseReg,
1665 LSRUse::KindType
Kind,
Type *AccessTy);
1667 std::pair<size_t, int64_t> getUse(
const SCEV *&Expr,
1668 LSRUse::KindType
Kind,
1671 void DeleteUse(LSRUse &LU,
size_t LUIdx);
1673 LSRUse *FindUseWithSimilarFormula(
const Formula &F,
const LSRUse &OrigLU);
1675 void InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
1676 void InsertSupplementalFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx);
1677 void CountRegisters(
const Formula &F,
size_t LUIdx);
1678 bool InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &F);
1680 void CollectLoopInvariantFixupsAndFormulae();
1682 void GenerateReassociations(LSRUse &LU,
unsigned LUIdx, Formula Base,
1683 unsigned Depth = 0);
1684 void GenerateCombinations(LSRUse &LU,
unsigned LUIdx, Formula Base);
1685 void GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx, Formula Base);
1686 void GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx, Formula Base);
1687 void GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx, Formula Base);
1688 void GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula Base);
1689 void GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula Base);
1690 void GenerateCrossUseConstantOffsets();
1691 void GenerateAllReuseFormulae();
1693 void FilterOutUndesirableDedicatedRegisters();
1695 size_t EstimateSearchSpaceComplexity()
const;
1696 void NarrowSearchSpaceByDetectingSupersets();
1697 void NarrowSearchSpaceByCollapsingUnrolledCode();
1698 void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
1699 void NarrowSearchSpaceByPickingWinnerRegs();
1700 void NarrowSearchSpaceUsingHeuristics();
1705 const Cost &CurCost,
1719 Value *Expand(
const LSRFixup &LF,
1724 void RewriteForPHI(
PHINode *PN,
const LSRFixup &LF,
1729 void Rewrite(
const LSRFixup &LF,
1740 bool getChanged()
const {
return Changed; }
1742 void print_factors_and_types(
raw_ostream &OS)
const;
1753 void LSRInstance::OptimizeShadowIV() {
1755 if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
1764 bool IsSigned =
false;
1778 if (
UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser())) {
1780 DestTy = UCast->getDestTy();
1782 else if (
SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser())) {
1784 DestTy = SCast->getDestTy();
1786 if (!DestTy)
continue;
1798 if (Mantissa == -1)
continue;
1802 unsigned Entry, Latch;
1812 if (!Init)
continue;
1813 Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
1819 if (!Incr)
continue;
1820 if (Incr->getOpcode() != Instruction::Add
1821 && Incr->getOpcode() != Instruction::Sub)
1826 if (Incr->getOperand(0) == PH)
1827 C = dyn_cast<ConstantInt>(Incr->getOperand(1));
1828 else if (Incr->getOperand(1) == PH)
1829 C = dyn_cast<ConstantInt>(Incr->getOperand(0));
1840 PHINode *NewPH = PHINode::Create(DestTy, 2,
"IV.S.", PH);
1845 BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
1846 Instruction::FAdd : Instruction::FSub,
1847 NewPH, CFP,
"IV.S.next.", Incr);
1865 if (UI->getUser() == Cond) {
1932 if (!Sel || !Sel->
hasOneUse())
return Cond;
1935 if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
1940 const SCEV *IterationCount = SE.
getAddExpr(One, BackedgeTakenCount);
1941 if (IterationCount != SE.
getSCEV(Sel))
return Cond;
1948 if (
const SCEVSMaxExpr *S = dyn_cast<SCEVSMaxExpr>(BackedgeTakenCount)) {
1949 Pred = ICmpInst::ICMP_SLE;
1951 }
else if (
const SCEVSMaxExpr *S = dyn_cast<SCEVSMaxExpr>(IterationCount)) {
1952 Pred = ICmpInst::ICMP_SLT;
1954 }
else if (
const SCEVUMaxExpr *U = dyn_cast<SCEVUMaxExpr>(IterationCount)) {
1955 Pred = ICmpInst::ICMP_ULT;
1986 "Loop condition operand is an addrec in a different loop!");
1994 if (
ConstantInt *BO1 = dyn_cast<ConstantInt>(BO->getOperand(1)))
1995 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
1996 NewRHS = BO->getOperand(0);
1998 if (
ConstantInt *BO1 = dyn_cast<ConstantInt>(BO->getOperand(1)))
1999 if (BO1->isOne() && SE.
getSCEV(BO->getOperand(0)) == MaxRHS)
2000 NewRHS = BO->getOperand(0);
2007 else if (
const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(MaxRHS))
2008 NewRHS = SU->getValue();
2016 Pred = CmpInst::getInversePredicate(Pred);
2037 LSRInstance::OptimizeLoopTermCond() {
2044 for (
unsigned i = 0, e = ExitingBlocks.
size(); i != e; ++i) {
2062 if (!FindIVUserForCond(Cond, CondUse))
2071 Cond = OptimizeMax(Cond, CondUse);
2076 if (!DT.
dominates(ExitingBlock, LatchBlock))
2081 if (LatchBlock != ExitingBlock)
2085 if (&*UI != CondUse &&
2089 const SCEV *
A = IU.getStride(*CondUse, L);
2090 const SCEV *B = IU.getStride(*UI, L);
2091 if (!A || !B)
continue;
2101 dyn_cast_or_null<SCEVConstant>(
getExactSDiv(B, A, SE))) {
2105 goto decline_post_inc;
2109 goto decline_post_inc;
2116 goto decline_post_inc;
2121 goto decline_post_inc;
2125 DEBUG(
dbgs() <<
" Change loop exiting icmp to use postinc iv: "
2137 Cond = cast<ICmpInst>(Cond->
clone());
2162 E = PostIncs.
end(); I != E; ++
I) {
2167 IVIncInsertPos = *I;
2168 else if (BB != IVIncInsertPos->
getParent())
2177 LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset,
bool HasBaseReg,
2178 LSRUse::KindType
Kind,
Type *AccessTy) {
2179 int64_t NewMinOffset = LU.MinOffset;
2180 int64_t NewMaxOffset = LU.MaxOffset;
2181 Type *NewAccessTy = AccessTy;
2186 if (LU.Kind != Kind)
2189 if (NewOffset < LU.MinOffset) {
2191 LU.MaxOffset - NewOffset, HasBaseReg))
2193 NewMinOffset = NewOffset;
2194 }
else if (NewOffset > LU.MaxOffset) {
2196 NewOffset - LU.MinOffset, HasBaseReg))
2198 NewMaxOffset = NewOffset;
2203 if (Kind == LSRUse::Address && AccessTy != LU.AccessTy)
2204 NewAccessTy = Type::getVoidTy(AccessTy->
getContext());
2207 LU.MinOffset = NewMinOffset;
2208 LU.MaxOffset = NewMaxOffset;
2209 LU.AccessTy = NewAccessTy;
2210 if (NewOffset != LU.Offsets.back())
2211 LU.Offsets.push_back(NewOffset);
2218 std::pair<size_t, int64_t>
2219 LSRInstance::getUse(
const SCEV *&Expr,
2220 LSRUse::KindType Kind,
Type *AccessTy) {
2221 const SCEV *Copy = Expr;
2231 std::pair<UseMapTy::iterator, bool>
P =
2232 UseMap.insert(std::make_pair(std::make_pair(Expr, Kind), 0));
2235 size_t LUIdx = P.first->second;
2236 LSRUse &LU = Uses[LUIdx];
2237 if (reconcileNewOffset(LU, Offset,
true, Kind, AccessTy))
2239 return std::make_pair(LUIdx, Offset);
2243 size_t LUIdx = Uses.size();
2244 P.first->second = LUIdx;
2245 Uses.push_back(LSRUse(Kind, AccessTy));
2246 LSRUse &LU = Uses[LUIdx];
2250 if (LU.Offsets.empty() || Offset != LU.Offsets.back())
2251 LU.Offsets.push_back(Offset);
2253 LU.MinOffset = Offset;
2254 LU.MaxOffset = Offset;
2255 return std::make_pair(LUIdx, Offset);
2259 void LSRInstance::DeleteUse(LSRUse &LU,
size_t LUIdx) {
2260 if (&LU != &Uses.back())
2265 RegUses.SwapAndDropUse(LUIdx, Uses.size());
2271 LSRInstance::FindUseWithSimilarFormula(
const Formula &OrigF,
2272 const LSRUse &OrigLU) {
2274 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
2275 LSRUse &LU = Uses[LUIdx];
2281 if (&LU != &OrigLU &&
2282 LU.Kind != LSRUse::ICmpZero &&
2283 LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
2284 LU.WidestFixupType == OrigLU.WidestFixupType &&
2285 LU.HasFormulaWithSameRegs(OrigF)) {
2288 E = LU.Formulae.end(); I != E; ++
I) {
2289 const Formula &F = *
I;
2292 if (F.BaseRegs == OrigF.BaseRegs &&
2293 F.ScaledReg == OrigF.ScaledReg &&
2294 F.BaseGV == OrigF.BaseGV &&
2295 F.Scale == OrigF.Scale &&
2296 F.UnfoldedOffset == OrigF.UnfoldedOffset) {
2297 if (F.BaseOffset == 0)
2312 void LSRInstance::CollectInterestingTypesAndFactors() {
2318 const SCEV *Expr = IU.getExpr(*UI);
2331 }
else if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
2332 Worklist.
append(Add->op_begin(), Add->op_end());
2334 }
while (!Worklist.
empty());
2339 I = Strides.
begin(), E = Strides.
end(); I != E; ++
I)
2341 llvm::next(I); NewStrideIter != E; ++NewStrideIter) {
2342 const SCEV *OldStride = *
I;
2343 const SCEV *NewStride = *NewStrideIter;
2354 dyn_cast_or_null<SCEVConstant>(
getExactSDiv(NewStride, OldStride,
2356 if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
2357 Factors.insert(Factor->getValue()->getValue().getSExtValue());
2362 if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
2363 Factors.insert(Factor->getValue()->getValue().getSExtValue());
2369 if (Types.size() == 1)
2381 for(; OI != OE; ++OI) {
2382 if (
Instruction *Oper = dyn_cast<Instruction>(*OI)) {
2387 dyn_cast<SCEVAddRecExpr>(SE.
getSCEV(Oper))) {
2399 if (
TruncInst *Trunc = dyn_cast<TruncInst>(Oper))
2400 return Trunc->getOperand(0);
2429 return getExprBase(cast<SCEVTruncateExpr>(S)->getOperand());
2431 return getExprBase(cast<SCEVZeroExtendExpr>(S)->getOperand());
2433 return getExprBase(cast<SCEVSignExtendExpr>(S)->getOperand());
2439 for (std::reverse_iterator<SCEVAddExpr::op_iterator>
I(Add->
op_end()),
2441 const SCEV *SubExpr = *
I;
2451 return getExprBase(cast<SCEVAddRecExpr>(S)->getStart());
2460 bool IVChain::isProfitableIncrement(
const SCEV *OperExpr,
2461 const SCEV *IncExpr,
2469 if (!isa<SCEVConstant>(IncExpr)) {
2471 if (isa<SCEVConstant>(SE.
getMinusSCEV(OperExpr, HeadExpr)))
2495 if (!Chain.hasIncs())
2498 if (!Users.
empty()) {
2499 DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" users:\n";
2501 E = Users.
end(); I != E; ++
I) {
2502 dbgs() <<
" " << **I <<
"\n";
2506 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
2514 if (isa<PHINode>(Chain.tailUserInst())
2515 && SE.
getSCEV(Chain.tailUserInst()) == Chain.Incs[0].IncExpr) {
2518 const SCEV *LastIncExpr = 0;
2519 unsigned NumConstIncrements = 0;
2520 unsigned NumVarIncrements = 0;
2521 unsigned NumReusedIncrements = 0;
2522 for (IVChain::const_iterator I = Chain.begin(), E = Chain.end();
2525 if (I->IncExpr->isZero())
2530 if (isa<SCEVConstant>(I->IncExpr)) {
2531 ++NumConstIncrements;
2535 if (I->IncExpr == LastIncExpr)
2536 ++NumReusedIncrements;
2540 LastIncExpr = I->IncExpr;
2545 if (NumConstIncrements > 1)
2552 cost += NumVarIncrements;
2556 cost -= NumReusedIncrements;
2558 DEBUG(
dbgs() <<
"Chain: " << *Chain.Incs[0].UserInst <<
" Cost: " << cost
2576 unsigned ChainIdx = 0, NChains = IVChainVec.size();
2577 const SCEV *LastIncExpr = 0;
2578 for (; ChainIdx < NChains; ++ChainIdx) {
2579 IVChain &Chain = IVChainVec[ChainIdx];
2593 if (isa<PHINode>(UserInst) && isa<PHINode>(Chain.tailUserInst()))
2602 if (Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
2603 LastIncExpr = IncExpr;
2609 if (ChainIdx == NChains) {
2610 if (isa<PHINode>(UserInst))
2616 LastIncExpr = OperExpr;
2620 if (!isa<SCEVAddRecExpr>(LastIncExpr))
2623 IVChainVec.push_back(IVChain(IVInc(UserInst, IVOper, LastIncExpr),
2625 ChainUsersVec.
resize(NChains);
2626 DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Head: (" << *UserInst
2627 <<
") IV=" << *LastIncExpr <<
"\n");
2629 DEBUG(
dbgs() <<
"IV Chain#" << ChainIdx <<
" Inc: (" << *UserInst
2630 <<
") IV+" << *LastIncExpr <<
"\n");
2632 IVChainVec[ChainIdx].add(IVInc(UserInst, IVOper, LastIncExpr));
2634 IVChain &Chain = IVChainVec[ChainIdx];
2638 if (!LastIncExpr->
isZero()) {
2639 ChainUsersVec[ChainIdx].FarUsers.
insert(NearUsers.
begin(),
2650 UseEnd = IVOper->
use_end(); UseIter != UseEnd; ++UseIter) {
2656 IVChain::const_iterator IncIter = Chain.Incs.begin();
2657 IVChain::const_iterator IncEnd = Chain.Incs.end();
2658 for( ; IncIter != IncEnd; ++IncIter) {
2659 if (IncIter->UserInst == OtherUse)
2662 if (IncIter != IncEnd)
2666 && !isa<SCEVUnknown>(SE.
getSCEV(OtherUse))
2667 && IU.isIVUserOrOperand(OtherUse)) {
2670 NearUsers.
insert(OtherUse);
2675 ChainUsersVec[ChainIdx].FarUsers.
erase(UserInst);
2700 void LSRInstance::CollectChains() {
2701 DEBUG(
dbgs() <<
"Collecting IV Chains.\n");
2707 Rung->
getBlock() != LoopHeader; Rung = Rung->getIDom()) {
2714 BBIter = LatchPath.
rbegin(), BBEnd = LatchPath.
rend();
2715 BBIter != BBEnd; ++BBIter) {
2719 if (isa<PHINode>(I) || !IU.isIVUserOrOperand(I))
2729 for (
unsigned ChainIdx = 0, NChains = IVChainVec.size();
2730 ChainIdx < NChains; ++ChainIdx) {
2731 ChainUsersVec[ChainIdx].NearUsers.
erase(I);
2737 while (IVOpIter != IVOpEnd) {
2738 Instruction *IVOpInst = cast<Instruction>(*IVOpIter);
2739 if (UniqueOperands.
insert(IVOpInst))
2740 ChainInstruction(I, IVOpInst, ChainUsersVec);
2754 ChainInstruction(PN, IncV, ChainUsersVec);
2757 unsigned ChainIdx = 0;
2758 for (
unsigned UsersIdx = 0, NChains = IVChainVec.size();
2759 UsersIdx < NChains; ++UsersIdx) {
2761 ChainUsersVec[UsersIdx].FarUsers, SE, TTI))
2764 if (ChainIdx != UsersIdx)
2765 IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
2766 FinalizeChain(IVChainVec[ChainIdx]);
2769 IVChainVec.resize(ChainIdx);
2772 void LSRInstance::FinalizeChain(IVChain &Chain) {
2773 assert(!Chain.Incs.empty() &&
"empty IV chains are not allowed");
2774 DEBUG(
dbgs() <<
"Final Chain: " << *Chain.Incs[0].UserInst <<
"\n");
2776 for (IVChain::const_iterator I = Chain.begin(), E = Chain.end();
2778 DEBUG(
dbgs() <<
" Inc: " << *I->UserInst <<
"\n");
2780 std::find(I->UserInst->op_begin(), I->UserInst->op_end(), I->IVOperand);
2781 assert(UseI != I->UserInst->op_end() &&
"cannot find IV operand");
2782 IVIncSet.insert(UseI);
2811 const IVInc &Head = Chain.Incs[0];
2817 while (IVOpIter != IVOpEnd) {
2828 if (SE.
getSCEV(*IVOpIter) == Head.IncExpr
2829 || SE.
getSCEV(IVSrc) == Head.IncExpr) {
2834 if (IVOpIter == IVOpEnd) {
2836 DEBUG(
dbgs() <<
"Concealed chain head: " << *Head.UserInst <<
"\n");
2840 DEBUG(
dbgs() <<
"Generate chain at: " << *IVSrc <<
"\n");
2841 Type *IVTy = IVSrc->getType();
2843 const SCEV *LeftOverExpr = 0;
2844 for (IVChain::const_iterator IncI = Chain.begin(),
2845 IncE = Chain.end(); IncI != IncE; ++IncI) {
2848 if (isa<PHINode>(InsertPt))
2849 InsertPt = L->getLoopLatch()->getTerminator();
2853 Value *IVOper = IVSrc;
2854 if (!IncI->IncExpr->isZero()) {
2858 LeftOverExpr = LeftOverExpr ?
2859 SE.
getAddExpr(LeftOverExpr, IncExpr) : IncExpr;
2861 if (LeftOverExpr && !LeftOverExpr->
isZero()) {
2867 IVOper = Rewriter.
expandCodeFor(IVOperExpr, IVTy, InsertPt);
2872 assert(IVTy == IVOper->
getType() &&
"inconsistent IV increment type");
2877 Type *OperTy = IncI->IVOperand->getType();
2878 if (IVTy != OperTy) {
2880 "cannot extend a chained IV");
2882 IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy,
"lsr.chain");
2884 IncI->UserInst->replaceUsesOfWith(IncI->IVOperand, IVOper);
2889 if (isa<PHINode>(Chain.tailUserInst())) {
2898 Value *IVOper = IVSrc;
2900 if (IVTy != PostIncTy) {
2901 assert(PostIncTy->
isPointerTy() &&
"mixing int/ptr IV types");
2902 IRBuilder<> Builder(L->getLoopLatch()->getTerminator());
2904 IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy,
"lsr.chain");
2912 void LSRInstance::CollectFixupsAndInitialFormulae() {
2917 UI->getOperandValToReplace());
2918 assert(UseI != UserInst->
op_end() &&
"cannot find IV operand");
2919 if (IVIncSet.count(UseI))
2923 LSRFixup &LF = getNewFixup();
2924 LF.UserInst = UserInst;
2925 LF.OperandValToReplace = UI->getOperandValToReplace();
2926 LF.PostIncLoops = UI->getPostIncLoops();
2928 LSRUse::KindType Kind = LSRUse::Basic;
2930 if (
isAddressUse(LF.UserInst, LF.OperandValToReplace)) {
2931 Kind = LSRUse::Address;
2935 const SCEV *S = IU.getExpr(*UI);
2943 if (
ICmpInst *CI = dyn_cast<ICmpInst>(LF.UserInst))
2944 if (CI->isEquality()) {
2947 Value *
NV = CI->getOperand(1);
2948 if (NV == LF.OperandValToReplace) {
2949 CI->setOperand(1, CI->getOperand(0));
2950 CI->setOperand(0, NV);
2951 NV = CI->getOperand(1);
2961 LF.PostIncLoops, SE, DT);
2962 Kind = LSRUse::ICmpZero;
2968 for (
size_t i = 0, e = Factors.size(); i != e; ++i)
2969 if (Factors[i] != -1)
2970 Factors.insert(-(uint64_t)Factors[i]);
2975 std::pair<size_t, int64_t> P = getUse(S, Kind, AccessTy);
2977 LF.Offset = P.second;
2978 LSRUse &LU = Uses[LF.LUIdx];
2979 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
2980 if (!LU.WidestFixupType ||
2983 LU.WidestFixupType = LF.OperandValToReplace->getType();
2986 if (LU.Formulae.empty()) {
2987 InsertInitialFormula(S, LU, LF.LUIdx);
2988 CountRegisters(LU.Formulae.back(), LF.LUIdx);
2999 LSRInstance::InsertInitialFormula(
const SCEV *S, LSRUse &LU,
size_t LUIdx) {
3002 LU.RigidFormula =
true;
3005 F.InitialMatch(S, L, SE);
3006 bool Inserted = InsertFormula(LU, LUIdx, F);
3007 assert(Inserted &&
"Initial formula already exists!"); (void)Inserted;
3013 LSRInstance::InsertSupplementalFormula(
const SCEV *S,
3014 LSRUse &LU,
size_t LUIdx) {
3016 F.BaseRegs.push_back(S);
3017 F.HasBaseReg =
true;
3018 bool Inserted = InsertFormula(LU, LUIdx, F);
3019 assert(Inserted &&
"Supplemental formula already exists!"); (void)Inserted;
3024 void LSRInstance::CountRegisters(
const Formula &F,
size_t LUIdx) {
3026 RegUses.CountRegister(F.ScaledReg, LUIdx);
3028 E = F.BaseRegs.end(); I != E; ++
I)
3029 RegUses.CountRegister(*I, LUIdx);
3034 bool LSRInstance::InsertFormula(LSRUse &LU,
unsigned LUIdx,
const Formula &F) {
3035 if (!LU.InsertFormula(F))
3038 CountRegisters(F, LUIdx);
3048 LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
3052 while (!Worklist.
empty()) {
3056 Worklist.
append(N->op_begin(), N->op_end());
3057 else if (
const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
3059 else if (
const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S)) {
3062 }
else if (
const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
3063 if (!Inserted.
insert(U))
continue;
3064 const Value *V = U->getValue();
3065 if (
const Instruction *Inst = dyn_cast<Instruction>(V)) {
3067 if (L->contains(Inst))
continue;
3068 }
else if (isa<UndefValue>(V))
3082 const BasicBlock *UseBB = !isa<PHINode>(UserInst) ?
3084 cast<PHINode>(UserInst)->getIncomingBlock(
3085 PHINode::getIncomingValueNumForOperand(UI.getOperandNo()));
3086 if (!DT.
dominates(L->getHeader(), UseBB))
3091 const SCEV *UserS = SE.
getSCEV(const_cast<Instruction *>(UserInst));
3093 if (!isa<SCEVUnknown>(UserS))
3097 SE.
getUnknown(const_cast<Instruction *>(UserInst)));
3102 if (
const ICmpInst *ICI = dyn_cast<ICmpInst>(UserInst)) {
3103 unsigned OtherIdx = !UI.getOperandNo();
3104 Value *OtherOp =
const_cast<Value *
>(ICI->getOperand(OtherIdx));
3109 LSRFixup &LF = getNewFixup();
3110 LF.UserInst =
const_cast<Instruction *
>(UserInst);
3111 LF.OperandValToReplace = UI.getUse();
3112 std::pair<size_t, int64_t> P = getUse(S, LSRUse::Basic, 0);
3114 LF.Offset = P.second;
3115 LSRUse &LU = Uses[LF.LUIdx];
3116 LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
3117 if (!LU.WidestFixupType ||
3120 LU.WidestFixupType = LF.OperandValToReplace->getType();
3121 InsertSupplementalFormula(U, LU, LF.LUIdx);
3122 CountRegisters(LU.Formulae.back(), Uses.size() - 1);
3138 unsigned Depth = 0) {
3143 if (
const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
3145 for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
3152 }
else if (
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
3158 C, Ops, L, SE, Depth+1);
3161 if (Remainder && (AR->
getLoop() == L || !isa<SCEVAddRecExpr>(Remainder))) {
3162 Ops.push_back(C ? SE.getMulExpr(C, Remainder) : Remainder);
3167 Remainder = SE.getConstant(AR->
getType(), 0);
3168 return SE.getAddRecExpr(Remainder,
3174 }
else if (
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
3176 if (Mul->getNumOperands() != 2)
3179 dyn_cast<SCEVConstant>(Mul->getOperand(0))) {
3180 C = C ? cast<SCEVConstant>(SE.
getMulExpr(C, Op0)) : Op0;
3181 const SCEV *Remainder =
3184 Ops.push_back(SE.getMulExpr(C, Remainder));
3193 void LSRInstance::GenerateReassociations(LSRUse &LU,
unsigned LUIdx,
3197 if (Depth >= 3)
return;
3199 for (
size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
3200 const SCEV *BaseReg = Base.BaseRegs[i];
3207 if (AddOps.
size() == 1)
continue;
3210 JE = AddOps.
end(); J != JE; ++J) {
3220 LU.AccessTy, *J, Base.getNumRegs() > 1))
3231 if (InnerAddOps.size() == 1 &&
3233 LU.AccessTy, InnerAddOps[0], Base.getNumRegs() > 1))
3247 F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset +
3249 F.BaseRegs.erase(F.BaseRegs.begin() + i);
3251 F.BaseRegs[i] = InnerSum;
3258 F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset +
3261 F.BaseRegs.push_back(*J);
3263 if (InsertFormula(LU, LUIdx, F))
3266 GenerateReassociations(LU, LUIdx, LU.Formulae.back(), Depth+1);
3273 void LSRInstance::GenerateCombinations(LSRUse &LU,
unsigned LUIdx,
3276 if (Base.BaseRegs.size() <= 1)
return;
3282 I = Base.BaseRegs.begin(), E = Base.BaseRegs.end(); I != E; ++
I) {
3283 const SCEV *BaseReg = *
I;
3288 F.BaseRegs.push_back(BaseReg);
3290 if (Ops.
size() > 1) {
3296 F.BaseRegs.push_back(Sum);
3297 (void)InsertFormula(LU, LUIdx, F);
3303 void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU,
unsigned LUIdx,
3306 if (Base.BaseGV)
return;
3308 for (
size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
3309 const SCEV *
G = Base.BaseRegs[i];
3315 if (!
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
3318 (void)InsertFormula(LU, LUIdx, F);
3323 void LSRInstance::GenerateConstantOffsets(LSRUse &LU,
unsigned LUIdx,
3329 if (LU.MaxOffset != LU.MinOffset)
3332 for (
size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
3333 const SCEV *G = Base.BaseRegs[i];
3336 E = Worklist.
end(); I != E; ++
I) {
3338 F.BaseOffset = (uint64_t)Base.BaseOffset - *I;
3339 if (
isLegalUse(TTI, LU.MinOffset - *I, LU.MaxOffset - *I, LU.Kind,
3345 std::swap(F.BaseRegs[i], F.BaseRegs.back());
3346 F.BaseRegs.pop_back();
3348 F.BaseRegs[i] = NewG;
3350 (void)InsertFormula(LU, LUIdx, F);
3355 if (G->
isZero() || Imm == 0)
3358 F.BaseOffset = (uint64_t)F.BaseOffset + Imm;
3359 if (!
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
3362 (void)InsertFormula(LU, LUIdx, F);
3368 void LSRInstance::GenerateICmpZeroScales(LSRUse &LU,
unsigned LUIdx,
3370 if (LU.Kind != LSRUse::ICmpZero)
return;
3373 Type *IntTy = Base.getType();
3378 if (LU.MinOffset != LU.MaxOffset)
return;
3380 assert(!Base.BaseGV &&
"ICmpZero use is not legal!");
3384 I = Factors.
begin(), E = Factors.end(); I != E; ++
I) {
3385 int64_t Factor = *
I;
3388 if (Base.BaseOffset == INT64_MIN && Factor == -1)
3390 int64_t NewBaseOffset = (uint64_t)Base.BaseOffset * Factor;
3391 if (NewBaseOffset / Factor != Base.BaseOffset)
3395 int64_t Offset = LU.MinOffset;
3396 if (Offset == INT64_MIN && Factor == -1)
3398 Offset = (uint64_t)Offset * Factor;
3399 if (Offset / Factor != LU.MinOffset)
3403 F.BaseOffset = NewBaseOffset;
3406 if (!
isLegalUse(TTI, Offset, Offset, LU.Kind, LU.AccessTy, F))
3410 F.BaseOffset = (uint64_t)F.BaseOffset + Offset - LU.MinOffset;
3415 for (
size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
3416 F.BaseRegs[i] = SE.
getMulExpr(F.BaseRegs[i], FactorS);
3417 if (
getExactSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i])
3423 F.ScaledReg = SE.
getMulExpr(F.ScaledReg, FactorS);
3424 if (
getExactSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg)
3429 if (F.UnfoldedOffset != 0) {
3430 if (F.UnfoldedOffset == INT64_MIN && Factor == -1)
3432 F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset * Factor;
3433 if (F.UnfoldedOffset / Factor != Base.UnfoldedOffset)
3438 (void)InsertFormula(LU, LUIdx, F);
3445 void LSRInstance::GenerateScales(LSRUse &LU,
unsigned LUIdx, Formula Base) {
3447 Type *IntTy = Base.getType();
3451 if (Base.Scale != 0)
return;
3455 I = Factors.
begin(), E = Factors.end(); I != E; ++
I) {
3456 int64_t Factor = *
I;
3458 Base.Scale = Factor;
3459 Base.HasBaseReg = Base.BaseRegs.size() > 1;
3461 if (!
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
3465 if (LU.Kind == LSRUse::Basic &&
3466 isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
3467 LU.AccessTy, Base) &&
3468 LU.AllFixupsOutsideLoop)
3469 LU.Kind = LSRUse::Special;
3475 if (LU.Kind == LSRUse::ICmpZero &&
3476 !Base.HasBaseReg && Base.BaseOffset == 0 && !Base.BaseGV)
3479 for (
size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
3481 dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i])) {
3490 F.ScaledReg = Quotient;
3491 F.DeleteBaseReg(F.BaseRegs[i]);
3492 (void)InsertFormula(LU, LUIdx, F);
3499 void LSRInstance::GenerateTruncates(LSRUse &LU,
unsigned LUIdx, Formula Base) {
3501 if (Base.BaseGV)
return;
3504 Type *DstTy = Base.getType();
3509 I = Types.
begin(), E = Types.end(); I != E; ++
I) {
3516 JE = F.BaseRegs.end(); J != JE; ++J)
3521 if (!F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
3524 (void)InsertFormula(LU, LUIdx, F);
3537 const SCEV *OrigReg;
3539 WorkItem(
size_t LI, int64_t I,
const SCEV *R)
3540 : LUIdx(LI), Imm(I), OrigReg(R) {}
3549 OS <<
"in formulae referencing " << *OrigReg <<
" in use " << LUIdx
3550 <<
" , add offset " << Imm;
3553 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3561 void LSRInstance::GenerateCrossUseConstantOffsets() {
3563 typedef std::map<int64_t, const SCEV *> ImmMapTy;
3568 for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
3570 const SCEV *Reg = *
I;
3572 std::pair<RegMapTy::iterator, bool> Pair =
3573 Map.insert(std::make_pair(Reg, ImmMapTy()));
3576 Pair.first->second.insert(std::make_pair(Imm, *I));
3577 UsedByIndicesMap[
Reg] |= RegUses.getUsedByIndices(*I);
3586 E = Sequence.
end(); I != E; ++
I) {
3587 const SCEV *Reg = *
I;
3588 const ImmMapTy &Imms = Map.find(Reg)->second;
3591 if (Imms.size() == 1)
3594 DEBUG(
dbgs() <<
"Generating cross-use offsets for " << *Reg <<
':';
3595 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
3597 dbgs() <<
' ' << J->first;
3601 for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
3603 const SCEV *OrigReg = J->second;
3605 int64_t JImm = J->first;
3606 const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
3608 if (!isa<SCEVConstant>(OrigReg) &&
3609 UsedByIndicesMap[Reg].count() == 1) {
3610 DEBUG(
dbgs() <<
"Skipping cross-use reuse for " << *OrigReg <<
'\n');
3616 ImmMapTy::const_iterator OtherImms[] = {
3617 Imms.begin(),
prior(Imms.end()),
3618 Imms.lower_bound((Imms.begin()->first +
prior(Imms.end())->first) / 2)
3621 ImmMapTy::const_iterator M = OtherImms[i];
3622 if (M == J || M == JE)
continue;
3625 int64_t Imm = (uint64_t)JImm - M->first;
3629 if (UniqueItems.
insert(std::make_pair(LUIdx, Imm)))
3630 WorkItems.
push_back(WorkItem(LUIdx, Imm, OrigReg));
3637 UsedByIndicesMap.
clear();
3638 UniqueItems.
clear();
3642 E = WorkItems.
end(); I != E; ++
I) {
3643 const WorkItem &WI = *
I;
3644 size_t LUIdx = WI.LUIdx;
3645 LSRUse &LU = Uses[LUIdx];
3646 int64_t Imm = WI.Imm;
3647 const SCEV *OrigReg = WI.OrigReg;
3650 const SCEV *NegImmS = SE.
getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm));
3654 for (
size_t L = 0,
LE = LU.Formulae.size(); L !=
LE; ++L) {
3655 const Formula &F = LU.Formulae[L];
3657 if (F.ScaledReg == OrigReg) {
3658 int64_t Offset = (uint64_t)F.BaseOffset + Imm * (uint64_t)F.Scale;
3660 if (F.referencesReg(SE.
getSCEV(
3661 ConstantInt::get(IntTy, -(uint64_t)Offset))))
3664 NewF.BaseOffset = Offset;
3665 if (!
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
3668 NewF.ScaledReg = SE.
getAddExpr(NegImmS, NewF.ScaledReg);
3673 if (
const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
3675 (NewF.BaseOffset < 0) &&
3677 .ule(
abs64(NewF.BaseOffset)))
3681 (void)InsertFormula(LU, LUIdx, NewF);
3684 for (
size_t N = 0,
NE = F.BaseRegs.size(); N !=
NE; ++
N) {
3685 const SCEV *BaseReg = F.BaseRegs[
N];
3686 if (BaseReg != OrigReg)
3689 NewF.BaseOffset = (uint64_t)NewF.BaseOffset + Imm;
3691 LU.Kind, LU.AccessTy, NewF)) {
3695 NewF.UnfoldedOffset = (uint64_t)NewF.UnfoldedOffset + Imm;
3697 NewF.BaseRegs[
N] = SE.
getAddExpr(NegImmS, BaseReg);
3703 J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
3705 if (
const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
3706 if ((C->
getValue()->getValue() + NewF.BaseOffset).
abs().slt(
3707 abs64(NewF.BaseOffset)) &&
3710 countTrailingZeros<uint64_t>(NewF.BaseOffset))
3714 (void)InsertFormula(LU, LUIdx, NewF);
3725 LSRInstance::GenerateAllReuseFormulae() {
3728 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3729 LSRUse &LU = Uses[LUIdx];
3730 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3731 GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
3732 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3733 GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
3735 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3736 LSRUse &LU = Uses[LUIdx];
3737 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3738 GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
3739 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3740 GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
3741 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3742 GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
3743 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3744 GenerateScales(LU, LUIdx, LU.Formulae[i]);
3746 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3747 LSRUse &LU = Uses[LUIdx];
3748 for (
size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
3749 GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
3752 GenerateCrossUseConstantOffsets();
3755 "After generating reuse formulae:\n";
3756 print_uses(
dbgs()));
3761 void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
3766 bool ChangedFormulae =
false;
3773 BestFormulaeTy BestFormulae;
3775 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3776 LSRUse &LU = Uses[LUIdx];
3780 for (
size_t FIdx = 0, NumForms = LU.Formulae.size();
3781 FIdx != NumForms; ++FIdx) {
3782 Formula &F = LU.Formulae[FIdx];
3793 CostF.RateFormula(TTI, F, Regs, VisitedRegs, L, LU.Offsets, SE, DT, LU,
3795 if (CostF.isLoser()) {
3808 JE = F.BaseRegs.end(); J != JE; ++J) {
3809 const SCEV *Reg = *J;
3810 if (RegUses.isRegUsedByUsesOtherThan(Reg, LUIdx))
3814 RegUses.isRegUsedByUsesOtherThan(F.ScaledReg, LUIdx))
3820 std::pair<BestFormulaeTy::const_iterator, bool> P =
3821 BestFormulae.insert(std::make_pair(Key, FIdx));
3825 Formula &Best = LU.Formulae[P.first->second];
3829 CostBest.RateFormula(TTI, Best, Regs, VisitedRegs, L, LU.Offsets, SE,
3831 if (CostF < CostBest)
3835 " in favor of formula "; Best.print(
dbgs());
3839 ChangedFormulae =
true;
3841 LU.DeleteFormula(F);
3849 LU.RecomputeRegs(LUIdx, RegUses);
3852 BestFormulae.clear();
3855 DEBUG(
if (ChangedFormulae) {
3857 "After filtering out undesirable candidates:\n";
3869 size_t LSRInstance::EstimateSearchSpaceComplexity()
const {
3872 E = Uses.end(); I != E; ++
I) {
3873 size_t FSize = I->Formulae.size();
3874 if (FSize >= ComplexityLimit) {
3879 if (Power >= ComplexityLimit)
3889 void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
3890 if (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
3891 DEBUG(
dbgs() <<
"The search space is too complex.\n");
3893 DEBUG(
dbgs() <<
"Narrowing the search space by eliminating formulae "
3894 "which use a superset of registers used by other "
3897 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3898 LSRUse &LU = Uses[LUIdx];
3900 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
3901 Formula &F = LU.Formulae[i];
3906 I = F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++
I) {
3907 if (
const SCEVConstant *C = dyn_cast<SCEVConstant>(*I)) {
3910 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
3911 (I - F.BaseRegs.begin()));
3912 if (LU.HasFormulaWithSameRegs(NewF)) {
3914 LU.DeleteFormula(F);
3920 }
else if (
const SCEVUnknown *U = dyn_cast<SCEVUnknown>(*I)) {
3921 if (
GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue()))
3925 NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
3926 (I - F.BaseRegs.begin()));
3927 if (LU.HasFormulaWithSameRegs(NewF)) {
3930 LU.DeleteFormula(F);
3941 LU.RecomputeRegs(LUIdx, RegUses);
3944 DEBUG(
dbgs() <<
"After pre-selection:\n";
3945 print_uses(
dbgs()));
3952 void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
3953 if (EstimateSearchSpaceComplexity() < ComplexityLimit)
3956 DEBUG(
dbgs() <<
"The search space is too complex.\n"
3957 "Narrowing the search space by assuming that uses separated "
3958 "by a constant offset will use the same registers.\n");
3962 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
3963 LSRUse &LU = Uses[LUIdx];
3965 E = LU.Formulae.end(); I != E; ++
I) {
3966 const Formula &F = *
I;
3967 if (F.BaseOffset == 0 || F.Scale != 0)
3970 LSRUse *LUThatHas = FindUseWithSimilarFormula(F, LU);
3974 if (!reconcileNewOffset(*LUThatHas, F.BaseOffset,
false,
3975 LU.Kind, LU.AccessTy))
3980 LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
3984 E =
Fixups.end(); I != E; ++
I) {
3985 LSRFixup &Fixup = *
I;
3986 if (Fixup.LUIdx == LUIdx) {
3987 Fixup.LUIdx = LUThatHas - &Uses.front();
3988 Fixup.Offset += F.BaseOffset;
3990 if (LUThatHas->Offsets.back() != Fixup.Offset) {
3991 LUThatHas->Offsets.push_back(Fixup.Offset);
3992 if (Fixup.Offset > LUThatHas->MaxOffset)
3993 LUThatHas->MaxOffset = Fixup.Offset;
3994 if (Fixup.Offset < LUThatHas->MinOffset)
3995 LUThatHas->MinOffset = Fixup.Offset;
3997 DEBUG(
dbgs() <<
"New fixup has offset " << Fixup.Offset <<
'\n');
3999 if (Fixup.LUIdx == NumUses-1)
4000 Fixup.LUIdx = LUIdx;
4005 for (
size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
4006 Formula &F = LUThatHas->Formulae[i];
4007 if (!
isLegalUse(TTI, LUThatHas->MinOffset, LUThatHas->MaxOffset,
4008 LUThatHas->Kind, LUThatHas->AccessTy, F)) {
4011 LUThatHas->DeleteFormula(F);
4019 LUThatHas->RecomputeRegs(LUThatHas - &Uses.front(), RegUses);
4022 DeleteUse(LU, LUIdx);
4029 DEBUG(
dbgs() <<
"After pre-selection:\n"; print_uses(
dbgs()));
4036 void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
4037 if (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
4038 DEBUG(
dbgs() <<
"The search space is too complex.\n");
4040 DEBUG(
dbgs() <<
"Narrowing the search space by re-filtering out "
4041 "undesirable dedicated registers.\n");
4043 FilterOutUndesirableDedicatedRegisters();
4045 DEBUG(
dbgs() <<
"After pre-selection:\n";
4046 print_uses(
dbgs()));
4053 void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
4057 while (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
4060 DEBUG(
dbgs() <<
"The search space is too complex.\n");
4064 const SCEV *Best = 0;
4065 unsigned BestNum = 0;
4066 for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
4068 const SCEV *Reg = *
I;
4069 if (Taken.
count(Reg))
4074 unsigned Count = RegUses.getUsedByIndices(Reg).count();
4075 if (Count > BestNum) {
4082 DEBUG(
dbgs() <<
"Narrowing the search space by assuming " << *Best
4083 <<
" will yield profitable reuse.\n");
4088 for (
size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
4089 LSRUse &LU = Uses[LUIdx];
4090 if (!LU.Regs.count(Best))
continue;
4093 for (
size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
4094 Formula &F = LU.Formulae[i];
4095 if (!F.referencesReg(Best)) {
4097 LU.DeleteFormula(F);
4101 assert(e != 0 &&
"Use has no formulae left! Is Regs inconsistent?");
4107 LU.RecomputeRegs(LUIdx, RegUses);
4110 DEBUG(
dbgs() <<
"After pre-selection:\n";
4111 print_uses(
dbgs()));
4119 void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
4120 NarrowSearchSpaceByDetectingSupersets();
4121 NarrowSearchSpaceByCollapsingUnrolledCode();
4122 NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
4123 NarrowSearchSpaceByPickingWinnerRegs();
4130 const Cost &CurCost,
4143 const LSRUse &LU = Uses[Workspace.
size()];
4151 E = CurRegs.
end(); I != E; ++
I)
4152 if (LU.Regs.count(*I))
4158 E = LU.Formulae.end(); I != E; ++
I) {
4159 const Formula &F = *
I;
4162 bool SatisfiedReqReg =
true;
4164 JE = ReqRegs.
end(); J != JE; ++J) {
4165 const SCEV *Reg = *J;
4166 if ((!F.ScaledReg || F.ScaledReg != Reg) &&
4167 std::find(F.BaseRegs.begin(), F.BaseRegs.end(),
Reg) ==
4169 SatisfiedReqReg =
false;
4173 if (!SatisfiedReqReg) {
4183 NewCost.RateFormula(TTI, F, NewRegs, VisitedRegs, L, LU.Offsets, SE, DT,
4185 if (NewCost < SolutionCost) {
4187 if (Workspace.
size() != Uses.size()) {
4188 SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
4189 NewRegs, VisitedRegs);
4190 if (F.getNumRegs() == 1 && Workspace.
size() == 1)
4191 VisitedRegs.
insert(F.ScaledReg ? F.ScaledReg : F.BaseRegs[0]);
4194 dbgs() <<
".\n Regs:";
4196 I = NewRegs.
begin(), E = NewRegs.
end(); I != E; ++
I)
4197 dbgs() <<
' ' << **
I;
4200 SolutionCost = NewCost;
4201 Solution = Workspace;
4213 SolutionCost.Loose();
4217 Workspace.
reserve(Uses.size());
4220 SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
4221 CurRegs, VisitedRegs);
4222 if (Solution.
empty()) {
4223 DEBUG(
dbgs() <<
"\nNo Satisfactory Solution\n");
4229 "The chosen solution requires "; SolutionCost.print(
dbgs());
4231 for (
size_t i = 0, e = Uses.size(); i != e; ++i) {
4233 Uses[i].print(
dbgs());
4236 Solution[i]->print(
dbgs());
4240 assert(Solution.
size() == Uses.size() &&
"Malformed solution!");
4252 const Loop *IPLoop =
LI.getLoopFor(IP->getParent());
4253 unsigned IPLoopDepth = IPLoop ? IPLoop->
getLoopDepth() : 0;
4257 if (!Rung)
return IP;
4258 Rung = Rung->getIDom();
4259 if (!Rung)
return IP;
4260 IDom = Rung->getBlock();
4263 const Loop *IDomLoop =
LI.getLoopFor(IDom);
4264 unsigned IDomDepth = IDomLoop ? IDomLoop->
getLoopDepth() : 0;
4265 if (IDomDepth <= IPLoopDepth &&
4266 (IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
4270 bool AllDominate =
true;
4274 E = Inputs.
end(); I != E; ++
I) {
4276 if (Inst == Tentative || !DT.
dominates(Inst, Tentative)) {
4277 AllDominate =
false;
4283 (!BetterPos || !DT.
dominates(Inst, BetterPos)))
4308 if (
Instruction *I = dyn_cast<Instruction>(LF.OperandValToReplace))
4310 if (LU.Kind == LSRUse::ICmpZero)
4312 dyn_cast<Instruction>(cast<ICmpInst>(LF.UserInst)->getOperand(1)))
4314 if (LF.PostIncLoops.count(L)) {
4315 if (LF.isUseFullyOutsideLoop(L))
4316 Inputs.
push_back(L->getLoopLatch()->getTerminator());
4323 E = LF.PostIncLoops.end(); I != E; ++
I) {
4324 const Loop *PIL = *
I;
4325 if (PIL == L)
continue;
4330 if (!ExitingBlocks.
empty()) {
4332 for (
unsigned i = 1, e = ExitingBlocks.
size(); i != e; ++i)
4338 assert(!isa<PHINode>(LowestIP) && !isa<LandingPadInst>(LowestIP)
4339 && !isa<DbgInfoIntrinsic>(LowestIP) &&
4340 "Insertion point must be a normal instruction");
4347 while (isa<PHINode>(IP)) ++IP;
4350 while (isa<LandingPadInst>(IP)) ++IP;
4353 while (isa<DbgInfoIntrinsic>(IP)) ++IP;
4365 Value *LSRInstance::Expand(
const LSRFixup &LF,
4370 const LSRUse &LU = Uses[LF.LUIdx];
4371 if (LU.RigidFormula)
4372 return LF.OperandValToReplace;
4376 IP = AdjustInsertPositionForExpand(IP, LF, LU, Rewriter);
4383 Type *OpTy = LF.OperandValToReplace->getType();
4385 Type *Ty = F.getType();
4400 E = F.BaseRegs.end(); I != E; ++
I) {
4401 const SCEV *Reg = *
I;
4402 assert(!Reg->
isZero() &&
"Zero allocated in a base register!");
4407 LF.UserInst, LF.OperandValToReplace,
4414 Value *ICmpScaledV = 0;
4416 const SCEV *ScaledS = F.ScaledReg;
4421 LF.UserInst, LF.OperandValToReplace,
4424 if (LU.Kind == LSRUse::ICmpZero) {
4428 assert(F.Scale == -1 &&
4429 "The only scale supported by ICmpZero uses is -1!");
4436 if (!Ops.
empty() && LU.Kind == LSRUse::Address) {
4468 int64_t Offset = (uint64_t)F.BaseOffset + LF.Offset;
4470 if (LU.Kind == LSRUse::ICmpZero) {
4474 ICmpScaledV = ConstantInt::get(IntTy, -(uint64_t)Offset);
4477 ICmpScaledV = ConstantInt::get(IntTy, Offset);
4487 int64_t UnfoldedOffset = F.UnfoldedOffset;
4488 if (UnfoldedOffset != 0) {
4506 if (LU.Kind == LSRUse::ICmpZero) {
4507 ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
4509 assert(!F.BaseGV &&
"ICmp does not support folding a global value and "
4510 "a scale at the same time!");
4511 if (F.Scale == -1) {
4512 if (ICmpScaledV->
getType() != OpTy) {
4514 CastInst::Create(CastInst::getCastOpcode(ICmpScaledV,
false,
4516 ICmpScaledV, OpTy,
"tmp", CI);
4521 assert(F.Scale == 0 &&
4522 "ICmp does not support folding a global value and "
4523 "a scale at the same time!");
4527 C = ConstantExpr::getCast(CastInst::getCastOpcode(C,
false,
4541 void LSRInstance::RewriteForPHI(
PHINode *PN,
4559 Loop *PNLoop =
LI.getLoopFor(Parent);
4560 if (!PNLoop || Parent != PNLoop->
getHeader()) {
4579 if (L->contains(BB) && !L->contains(PN))
4590 std::pair<DenseMap<BasicBlock *, Value *>::iterator,
bool> Pair =
4591 Inserted.
insert(std::make_pair(BB, static_cast<Value *>(0)));
4598 Type *OpTy = LF.OperandValToReplace->getType();
4601 CastInst::Create(CastInst::getCastOpcode(FullV,
false,
4603 FullV, LF.OperandValToReplace->getType(),
4607 Pair.first->second = FullV;
4615 void LSRInstance::Rewrite(
const LSRFixup &LF,
4622 if (
PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) {
4623 RewriteForPHI(PN, LF, F, Rewriter, DeadInsts, P);
4625 Value *FullV = Expand(LF, F, LF.UserInst, Rewriter, DeadInsts);
4628 Type *OpTy = LF.OperandValToReplace->getType();
4629 if (FullV->
getType() != OpTy) {
4631 CastInst::Create(CastInst::getCastOpcode(FullV,
false, OpTy,
false),
4632 FullV, OpTy,
"tmp", LF.UserInst);
4641 if (Uses[LF.LUIdx].Kind == LSRUse::ICmpZero)
4642 LF.UserInst->setOperand(0, FullV);
4644 LF.UserInst->replaceUsesOfWith(LF.OperandValToReplace, FullV);
4647 DeadInsts.
push_back(LF.OperandValToReplace);
4669 ChainE = IVChainVec.end(); ChainI != ChainE; ++ChainI) {
4670 if (
PHINode *PN = dyn_cast<PHINode>(ChainI->tailUserInst()))
4676 E =
Fixups.end(); I != E; ++
I) {
4677 const LSRFixup &Fixup = *
I;
4679 Rewrite(Fixup, *Solution[Fixup.LUIdx], Rewriter, DeadInsts, P);
4685 ChainE = IVChainVec.end(); ChainI != ChainE; ++ChainI) {
4686 GenerateIVChain(*ChainI, Rewriter, DeadInsts);
4696 LSRInstance::LSRInstance(
Loop *L,
Pass *P)
4706 if (IU.empty())
return;
4710 unsigned NumUsers = 0;
4713 DEBUG(
dbgs() <<
"LSR skipping loop, too many IV Users in " << *L
4727 Rung; Rung = Rung->
getIDom()) {
4729 const Loop *DomLoop =
LI.getLoopFor(BB);
4730 if (DomLoop && DomLoop->
getHeader() == BB) {
4742 OptimizeLoopTermCond();
4745 if (IU.empty())
return;
4749 DEBUG(
dbgs() <<
"LSR skipping outer loop " << *L <<
"\n");
4755 CollectInterestingTypesAndFactors();
4756 CollectFixupsAndInitialFormulae();
4757 CollectLoopInvariantFixupsAndFormulae();
4759 assert(!Uses.empty() &&
"IVUsers reported at least one use");
4760 DEBUG(
dbgs() <<
"LSR found " << Uses.size() <<
" uses:\n";
4761 print_uses(
dbgs()));
4765 GenerateAllReuseFormulae();
4767 FilterOutUndesirableDedicatedRegisters();
4768 NarrowSearchSpaceUsingHeuristics();
4778 if (Solution.
empty())
4785 const LSRUse &LU = *
I;
4787 JE = LU.Formulae.end();
4789 assert(
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
4790 *J) &&
"Illegal formula generated!");
4795 ImplementSolution(Solution, P);
4798 void LSRInstance::print_factors_and_types(
raw_ostream &OS)
const {
4799 if (Factors.empty() && Types.empty())
return;
4801 OS <<
"LSR has identified the following interesting factors and types: ";
4805 I = Factors.
begin(), E = Factors.end(); I != E; ++
I) {
4806 if (!First) OS <<
", ";
4812 I = Types.
begin(), E = Types.end(); I != E; ++
I) {
4813 if (!First) OS <<
", ";
4815 OS <<
'(' << **I <<
')';
4820 void LSRInstance::print_fixups(
raw_ostream &OS)
const {
4821 OS <<
"LSR is examining the following fixup sites:\n";
4823 E =
Fixups.end(); I != E; ++
I) {
4830 void LSRInstance::print_uses(
raw_ostream &OS)
const {
4831 OS <<
"LSR is examining the following uses:\n";
4833 E = Uses.end(); I != E; ++
I) {
4834 const LSRUse &LU = *
I;
4839 JE = LU.Formulae.end(); J != JE; ++J) {
4848 print_factors_and_types(OS);
4853 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4861 class LoopStrengthReduce :
public LoopPass {
4864 LoopStrengthReduce();
4875 "Loop Strength Reduction",
false,
false)
4887 return new LoopStrengthReduce();
4890 LoopStrengthReduce::LoopStrengthReduce() :
LoopPass(
ID) {
4894 void LoopStrengthReduce::getAnalysisUsage(
AnalysisUsage &AU)
const {
4915 bool Changed =
false;
4918 Changed |= LSRInstance(L,
this).getChanged();
4928 unsigned numFolded =
4931 &getAnalysis<TargetTransformInfo>());
void push_back(const T &Elt)
DomTreeNode * getNode(BasicBlock *BB) const
const_iterator end(StringRef path)
Get end iterator over path.
AnalysisUsage & addPreserved()
APInt LLVM_ATTRIBUTE_UNUSED_RESULT abs() const
Get the absolute value;.
static PassRegistry * getPassRegistry()
const SCEV * TransformForPostIncUse(TransformKind Kind, const SCEV *S, Instruction *User, Value *OperandValToReplace, PostIncLoopSet &Loops, ScalarEvolution &SE, DominatorTree &DT)
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
static bool isExistingPhi(const SCEVAddRecExpr *AR, ScalarEvolution &SE)
isExistingPhi - Return true if this AddRec is already a phi in its loop.
Pass * createLoopStrengthReducePass()
const SCEV * getConstant(ConstantInt *V)
static bool isLegalUse(const TargetTransformInfo &TTI, LSRUse::KindType Kind, Type *AccessTy, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale)
LLVMContext & getContext() const
BasicBlock * SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P=0, bool MergeIdenticalEdges=false, bool DontDeleteUselessPHIs=false, bool SplitLandingPads=false)
static const size_t ComplexityLimit
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual void getAnalysisUsage(AnalysisUsage &) const
static PointerType * get(Type *ElementType, unsigned AddressSpace)
static const unsigned MaxIVUsers
bool properlyDominates(const SCEV *S, const BasicBlock *BB)
bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
iterator insert(iterator I, const T &Elt)
void initializeLoopStrengthReducePass(PassRegistry &)
void setDebugType(const char *s)
const_iterator begin(StringRef path)
Get begin iterator over path.
int getFPMantissaWidth() const
bool isLoopInvariant(const SCEV *S, const Loop *L)
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
const Function * getParent() const
Return the enclosing method, or null if none.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
iv Induction Variable Users
bool isTrueWhenEqual(CondCode Cond)
iterator end()
Get an iterator to the end of the SetVector.
BlockT * getHeader() const
LoopInfoBase< BlockT, LoopT > * LI
const SCEV * getStart() const
BlockT * getLoopLatch() const
bool isNegative() const
Determine sign of this APInt.
DomTreeNodeBase< NodeT > * getIDom() const
void WriteAsOperand(raw_ostream &, const Value *, bool PrintTy=true, const Module *Context=0)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isUnconditional() const
const APInt & getValue() const
Return the constant's value.
void clearPostInc()
clearPostInc - Disable all post-inc expansion.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
static User::op_iterator findIVOperand(User::op_iterator OI, User::op_iterator OE, Loop *L, ScalarEvolution &SE)
const SCEV *const * op_iterator
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
uint64_t getTypeSizeInBits(Type *Ty) const
void setName(const Twine &Name)
static unsigned getScalingFactorCost(const TargetTransformInfo &TTI, const LSRUse &LU, const Formula &F)
ID
LLVM Calling Convention Representation.
Instruction * clone() const
op_iterator op_begin() const
bool isLoopSimplifyForm() const
uint64_t getZExtValue() const
Return the zero extended value.
bool insert(const value_type &X)
Insert a new element into the SetVector.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool count(PtrType Ptr) const
count - Return true if the specified pointer is in the set.
size_t array_lengthof(T(&)[N])
Find the length of an array.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
enable_if_c< std::numeric_limits< T >::is_integer &&!std::numeric_limits< T >::is_signed, std::size_t >::type countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, unsigned len)
General addition of 64-bit integer arrays.
iterator begin()
Get an iterator to the beginning of the SetVector.
AnalysisUsage & addPreservedID(const void *ID)
void replaceAllUsesWith(Value *V)
static bool isLegal2RegAMUse(const TargetTransformInfo &TTI, const LSRUse &LU, const Formula &F)
Type * getEffectiveSCEVType(Type *Ty) const
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
unsigned getMinSignedBits() const
Get the minimum bit size for this signed APInt.
This class represents a truncation of integer types.
const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags)
size_t getNumOperands() const
unsigned getNumIncomingValues() const
void replaceUsesOfWith(Value *From, Value *To)
unsigned getNumSuccessors() const
static bool isCompatibleIVType(Value *LVal, Value *RVal)
initializer< Ty > init(const Ty &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
bool isSCEVable(Type *Ty) const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
void setUser(Instruction *NewUser)
setUser - Assign a new user instruction for this use.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
BlockT * getLoopPreheader() const
static bool isAlwaysFoldable(const TargetTransformInfo &TTI, LSRUse::KindType Kind, Type *AccessTy, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg)
static bool isMulSExtable(const SCEVMulExpr *M, ScalarEvolution &SE)
LLVM Basic Block Representation.
static void DoInitialMatch(const SCEV *S, Loop *L, SmallVectorImpl< const SCEV * > &Good, SmallVectorImpl< const SCEV * > &Bad, ScalarEvolution &SE)
DoInitialMatch - Recursion helper for InitialMatch.
LLVM Constant Representation.
const SCEV * getOperand(unsigned i) const
int64_t getSExtValue() const
Get sign extended value.
Normalize - Normalize according to the given loops.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
static cl::opt< bool > EnablePhiElim("enable-lsr-phielim", cl::Hidden, cl::init(true), cl::desc("Enable LSR phi elimination"))
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
BasicBlock * getIncomingBlock(unsigned i) const
ItTy next(ItTy it, Dist n)
bool contains(const LoopT *L) const
const InstListType & getInstList() const
Return the underlying instruction list container.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Represent an integer comparison operator.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
iterator insert(iterator where, NodeTy *New)
Value * expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I)
int find_next(unsigned Prev) const
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE)
APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const
Signed division function for APInt.
Value * getOperand(unsigned i) const
static Type * getAccessType(const Instruction *Inst)
getAccessType - Return the type of the memory being accessed.
Predicate getPredicate() const
Return the predicate for this instruction.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static Constant * getAllOnesValue(Type *Ty)
Get the all ones value.
bool dominates(const DomTreeNode *A, const DomTreeNode *B) const
#define INITIALIZE_AG_DEPENDENCY(depName)
void append(in_iter in_start, in_iter in_end)
iterator erase(iterator I)
static bool isAddSExtable(const SCEVAddExpr *A, ScalarEvolution &SE)
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, SmallVectorImpl< WeakVH > &DeadInsts, const TargetTransformInfo *TTI=NULL)
APInt LLVM_ATTRIBUTE_UNUSED_RESULT srem(const APInt &RHS) const
Function for signed remainder operation.
void setChainedPhi(PHINode *PN)
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
static const SCEV * getExactSDiv(const SCEV *LHS, const SCEV *RHS, ScalarEvolution &SE, bool IgnoreSignificantBits=false)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
Get or create an IntegerType instance.
bool count(const ValueT &V) const
A SetVector that performs no allocations if smaller than a certain size.
void clear()
clear - Clear all bits.
std::pair< iterator, bool > insert(const ValueT &V)
Class for constant integers.
static bool isHighCostExpansion(const SCEV *S, SmallPtrSet< const SCEV *, 8 > &Processed, ScalarEvolution &SE)
Value * getIncomingValue(unsigned i) const
static cl::opt< bool > StressIVChain("stress-ivchain", cl::Hidden, cl::init(false), cl::desc("Stress test LSR IV chains"))
friend const_iterator begin(StringRef path)
Get begin iterator over path.
AnalysisUsage & addRequiredID(const void *ID)
Value * getOperandValToReplace() const
const SCEV * getNoopOrSignExtend(const SCEV *V, Type *Ty)
void setIVIncInsertPos(const Loop *L, Instruction *Pos)
setIVIncInsertPos - Set the current IV increment loop and position.
static Value * getWideOperand(Value *Oper)
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
ConstantInt * getValue() const
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
bool isAllOnesValue() const
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
size_t size() const
size - Returns the number of bits in this bitvector.
Class for arbitrary precision integers.
const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty)
Value * getIncomingValueForBlock(const BasicBlock *BB) const
static bool isAddressUse(Instruction *Inst, Value *OperandVal)
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
loop Loop Strength Reduction
virtual bool runOnLoop(Loop *L, LPPassManager &LPM)=0
Virtual Register Rewriter
bool isAllOnesValue() const
Determine if all bits are set.
Value * getCondition() const
bool isMinSignedValue() const
Determine if this is the smallest signed value.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isLandingPad() const
Return true if this basic block is a landing pad.
static const SCEV * getExprBase(const SCEV *S)
INITIALIZE_PASS_BEGIN(LoopStrengthReduce,"loop-reduce","Loop Strength Reduction", false, false) INITIALIZE_PASS_END(LoopStrengthReduce
This class represents a cast unsigned integer to floating point.
BasicBlock * findNearestCommonDominator(BasicBlock *A, BasicBlock *B)
const Loop * getLoop() const
static bool isProfitableChain(IVChain &Chain, SmallPtrSet< Instruction *, 4 > &Users, ScalarEvolution &SE, const TargetTransformInfo &TTI)
void transformToPostInc(const Loop *L)
static bool canFoldIVIncExpr(const SCEV *IncExpr, Instruction *UserInst, Value *Operand, const TargetTransformInfo &TTI)
Return true if the IVInc can be folded into an addressing mode.
const SCEV * getBackedgeTakenCount(const Loop *L)
This class represents a cast from signed integer to floating point.
static bool DeleteTriviallyDeadInstructions(SmallVectorImpl< WeakVH > &DeadInsts)
reverse_iterator rbegin()
unsigned getSCEVType() const
LLVM Value Representation.
const SCEV * getSCEV(Value *V)
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
static GlobalValue * ExtractSymbol(const SCEV *&S, ScalarEvolution &SE)
void moveBefore(Instruction *MovePos)
static const SCEV * CollectSubexprs(const SCEV *S, const SCEVConstant *C, SmallVectorImpl< const SCEV * > &Ops, const Loop *L, ScalarEvolution &SE, unsigned Depth=0)
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=0)
ItTy prior(ItTy it, Dist n)
bool isInsertedInstruction(Instruction *I) const
void disableCanonicalMode()
const SCEV * getUnknown(Value *V)
op_iterator op_end() const
void SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef< BasicBlock * > Preds, const char *Suffix, const char *Suffix2, Pass *P, SmallVectorImpl< BasicBlock * > &NewBBs)
bool hasComputableLoopEvolution(const SCEV *S, const Loop *L)
void setIncomingValue(unsigned i, Value *V)
void setPostInc(const PostIncLoopSet &L)
int64_t getSExtValue() const
Return the sign extended value.
bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE)
unsigned getLoopDepth() const
const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
int getBasicBlockIndex(const BasicBlock *BB) const
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...
const BasicBlock * getParent() const
bool isOne() const
Determine if the value is one.
static bool isAddRecSExtable(const SCEVAddRecExpr *AR, ScalarEvolution &SE)
const SCEV * getAnyExtendExpr(const SCEV *Op, Type *Ty)