26 #define DEBUG_TYPE "sroa"
60 STATISTIC(NumAllocasAnalyzed,
"Number of allocas analyzed for replacement");
61 STATISTIC(NumAllocaPartitions,
"Number of alloca partitions formed");
62 STATISTIC(MaxPartitionsPerAlloca,
"Maximum number of partitions per alloca");
63 STATISTIC(NumAllocaPartitionUses,
"Number of alloca partition uses rewritten");
64 STATISTIC(MaxUsesPerAllocaPartition,
"Maximum number of uses of a partition");
65 STATISTIC(NumNewAllocas,
"Number of new, smaller allocas introduced");
66 STATISTIC(NumPromoted,
"Number of allocas promoted to SSA values");
67 STATISTIC(NumLoadsSpeculated,
"Number of loads speculated to allow promotion");
68 STATISTIC(NumDeleted,
"Number of instructions deleted");
69 STATISTIC(NumVectorized,
"Number of vectorized aggregates");
79 template <
bool preserveNames = true>
80 class IRBuilderPrefixedInserter :
97 class IRBuilderPrefixedInserter<
false> :
100 void SetNamePrefix(
const Twine &P) {}
106 IRBuilderPrefixedInserter<true> > IRBuilderTy;
108 typedef llvm::IRBuilder<
false, ConstantFolder,
109 IRBuilderPrefixedInserter<false> > IRBuilderTy;
122 uint64_t BeginOffset;
132 Slice() : BeginOffset(), EndOffset() {}
133 Slice(uint64_t BeginOffset, uint64_t EndOffset,
Use *U,
bool IsSplittable)
134 : BeginOffset(BeginOffset), EndOffset(EndOffset),
135 UseAndIsSplittable(U, IsSplittable) {}
137 uint64_t beginOffset()
const {
return BeginOffset; }
138 uint64_t endOffset()
const {
return EndOffset; }
140 bool isSplittable()
const {
return UseAndIsSplittable.getInt(); }
141 void makeUnsplittable() { UseAndIsSplittable.setInt(
false); }
143 Use *getUse()
const {
return UseAndIsSplittable.getPointer(); }
145 bool isDead()
const {
return getUse() == 0; }
146 void kill() { UseAndIsSplittable.setPointer(0); }
155 if (beginOffset() < RHS.beginOffset())
return true;
156 if (beginOffset() > RHS.beginOffset())
return false;
157 if (isSplittable() != RHS.isSplittable())
return !isSplittable();
158 if (endOffset() > RHS.endOffset())
return true;
164 uint64_t RHSOffset) {
165 return LHS.beginOffset() < RHSOffset;
169 return LHSOffset < RHS.beginOffset();
173 return isSplittable() == RHS.isSplittable() &&
174 beginOffset() == RHS.beginOffset() && endOffset() == RHS.endOffset();
204 bool isEscaped()
const {
return PointerEscapingInstr; }
210 iterator
end() {
return Slices.
end(); }
213 const_iterator
begin()
const {
return Slices.
begin(); }
214 const_iterator
end()
const {
return Slices.
end(); }
224 dead_user_iterator dead_user_begin()
const {
return DeadUsers.
begin(); }
225 dead_user_iterator dead_user_end()
const {
return DeadUsers.end(); }
236 dead_op_iterator dead_op_begin()
const {
return DeadOperands.
begin(); }
237 dead_op_iterator dead_op_end()
const {
return DeadOperands.end(); }
240 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
252 template <
typename DerivedT,
typename RetT =
void>
class BuilderBase;
256 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
318 const uint64_t AllocSize;
330 AllocSize(DL.getTypeAllocSize(AI.getAllocatedType())), S(S) {}
334 if (VisitedDeadInsts.insert(&I))
335 S.DeadUsers.push_back(&I);
339 bool IsSplittable =
false) {
342 if (Size == 0 || Offset.
isNegative() || Offset.
uge(AllocSize)) {
343 DEBUG(
dbgs() <<
"WARNING: Ignoring " << Size <<
" byte use @" << Offset
344 <<
" which has zero size or starts outside of the "
345 << AllocSize <<
" byte alloca:\n"
346 <<
" alloca: " << S.AI <<
"\n"
347 <<
" use: " << I <<
"\n");
348 return markAsDead(I);
352 uint64_t EndOffset = BeginOffset + Size;
360 assert(AllocSize >= BeginOffset);
361 if (Size > AllocSize - BeginOffset) {
362 DEBUG(
dbgs() <<
"WARNING: Clamping a " << Size <<
" byte use @" << Offset
363 <<
" to remain within the " << AllocSize <<
" byte alloca:\n"
364 <<
" alloca: " << S.AI <<
"\n"
365 <<
" use: " << I <<
"\n");
366 EndOffset = AllocSize;
369 S.Slices.push_back(Slice(BeginOffset, EndOffset, U, IsSplittable));
374 return markAsDead(BC);
376 return Base::visitBitCastInst(BC);
381 return markAsDead(GEPI);
383 return Base::visitGetElementPtrInst(GEPI);
387 uint64_t Size,
bool IsVolatile) {
397 Ty->
isIntegerTy() && !IsVolatile && Offset == 0 && Size >= AllocSize;
399 insertUse(I, Offset, Size, IsSplittable);
404 "All simple FCA loads should have been pre-split");
407 return PI.setAborted(&LI);
416 return PI.setEscapedAndAborted(&SI);
418 return PI.setAborted(&SI);
429 if (Offset.isNegative() || Size > AllocSize ||
430 Offset.ugt(AllocSize - Size)) {
431 DEBUG(
dbgs() <<
"WARNING: Ignoring " << Size <<
" byte store @" << Offset
432 <<
" which extends past the end of the " << AllocSize
434 <<
" alloca: " << S.AI <<
"\n"
435 <<
" use: " << SI <<
"\n");
436 return markAsDead(SI);
440 "All simple FCA stores should have been pre-split");
446 assert(II.
getRawDest() == *U &&
"Pointer use is not the destination?");
448 if ((Length && Length->getValue() == 0) ||
449 (IsOffsetKnown && !Offset.isNegative() && Offset.uge(AllocSize)))
451 return markAsDead(II);
454 return PI.setAborted(&II);
456 insertUse(II, Offset,
457 Length ? Length->getLimitedValue()
458 : AllocSize - Offset.getLimitedValue(),
464 if ((Length && Length->
getValue() == 0) ||
465 (IsOffsetKnown && !Offset.isNegative() && Offset.uge(AllocSize)))
467 return markAsDead(II);
470 return PI.setAborted(&II);
472 uint64_t RawOffset = Offset.getLimitedValue();
474 : AllocSize - RawOffset;
481 return markAsDead(II);
483 return insertUse(II, Offset, Size,
false);
491 MemTransferSliceMap.insert(std::make_pair(&II, S.Slices.size()));
492 unsigned PrevIdx = MTPI->second;
494 Slice &PrevP = S.Slices[PrevIdx];
498 if (!II.
isVolatile() && PrevP.beginOffset() == RawOffset) {
500 return markAsDead(II);
505 PrevP.makeUnsplittable();
509 insertUse(II, Offset, Size, Inserted && Length);
512 assert(S.Slices[PrevIdx].getUse()->getUser() == &II &&
513 "Map index doesn't point back to a slice with this user.");
521 return PI.setAborted(&II);
526 uint64_t Size = std::min(AllocSize - Offset.getLimitedValue(),
528 insertUse(II, Offset, Size,
true);
532 Base::visitIntrinsicInst(II);
543 Uses.
push_back(std::make_pair(cast<Instruction>(*U), Root));
551 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
555 if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
564 if (!GEP->hasAllZeroIndices())
566 }
else if (!isa<BitCastInst>(I) && !isa<PHINode>(
I) &&
567 !isa<SelectInst>(I)) {
573 if (Visited.
insert(cast<Instruction>(*UI)))
574 Uses.
push_back(std::make_pair(I, cast<Instruction>(*UI)));
575 }
while (!Uses.
empty());
580 void visitPHINode(
PHINode &PN) {
582 return markAsDead(PN);
584 return PI.setAborted(&PN);
587 uint64_t &PHISize = PHIOrSelectSizes[&PN];
590 if (
Instruction *UnsafeI = hasUnsafePHIOrSelectUse(&PN, PHISize))
591 return PI.setAborted(UnsafeI);
600 if ((Offset.isNegative() && (-Offset).uge(PHISize)) ||
601 (!Offset.isNegative() && Offset.uge(AllocSize))) {
602 S.DeadOperands.push_back(U);
606 insertUse(PN, Offset, PHISize);
611 return markAsDead(SI);
620 S.DeadOperands.push_back(U);
625 return PI.setAborted(&SI);
628 uint64_t &SelectSize = PHIOrSelectSizes[&SI];
631 if (
Instruction *UnsafeI = hasUnsafePHIOrSelectUse(&SI, SelectSize))
632 return PI.setAborted(UnsafeI);
641 if ((Offset.isNegative() && Offset.uge(SelectSize)) ||
642 (!Offset.isNegative() && Offset.uge(AllocSize))) {
643 S.DeadOperands.push_back(U);
647 insertUse(SI, Offset, SelectSize);
658 #
if !defined(
NDEBUG) || defined(LLVM_ENABLE_DUMP)
661 PointerEscapingInstr(0) {
663 SliceBuilder::PtrInfo PtrI = PB.visitPtr(AI);
664 if (PtrI.isEscaped() || PtrI.isAborted()) {
667 PointerEscapingInstr = PtrI.getEscapingInst() ? PtrI.getEscapingInst()
668 : PtrI.getAbortingInst();
669 assert(PointerEscapingInstr &&
"Did not track a bad instruction");
673 Slices.erase(std::remove_if(Slices.begin(), Slices.end(),
674 std::mem_fun_ref(&Slice::isDead)),
679 std::sort(Slices.begin(), Slices.end());
682 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
684 void AllocaSlices::print(
raw_ostream &OS, const_iterator I,
686 printSlice(OS, I, Indent);
687 printUse(OS, I, Indent);
690 void AllocaSlices::printSlice(
raw_ostream &OS, const_iterator I,
692 OS << Indent <<
"[" << I->beginOffset() <<
"," << I->endOffset() <<
")"
693 <<
" slice #" << (I -
begin())
694 << (I->isSplittable() ?
" (splittable)" :
"") <<
"\n";
697 void AllocaSlices::printUse(
raw_ostream &OS, const_iterator I,
699 OS << Indent <<
" used by: " << *I->getUse()->getUser() <<
"\n";
703 if (PointerEscapingInstr) {
704 OS <<
"Can't analyze slices for alloca: " << AI <<
"\n"
705 <<
" A pointer to this alloca escaped by:\n"
706 <<
" " << *PointerEscapingInstr <<
"\n";
710 OS <<
"Slices of alloca: " << AI <<
"\n";
711 for (const_iterator I =
begin(), E =
end(); I != E; ++
I)
718 #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
743 if (
MDNode *DebugNode = MDNode::getIfExists(AI.getContext(), &AI)) {
745 UE = DebugNode->use_end();
749 else if (
DbgValueInst *DVI = dyn_cast<DbgValueInst>(*UI))
753 LoadAndStorePromoter::run(Insts);
757 while (!DDIs.empty())
758 DDIs.pop_back_val()->eraseFromParent();
759 while (!DVIs.empty())
760 DVIs.pop_back_val()->eraseFromParent();
766 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
780 Ptr = BCI->getOperand(0);
786 }
while (Visited.
insert(Ptr));
791 virtual void updateDebugInfo(
Instruction *Inst)
const {
793 E = DDIs.end(); I != E; ++
I) {
795 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst))
797 else if (
LoadInst *LI = dyn_cast<LoadInst>(Inst))
801 E = DVIs.end(); I != E; ++
I) {
804 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
812 Arg = SI->getValueOperand();
813 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
848 const bool RequiresDomTree;
879 std::vector<AllocaInst *> PromotableAllocas;
897 SROA(
bool RequiresDomTree =
true)
905 const char *getPassName()
const {
return "SROA"; }
909 friend class PHIOrSelectSpeculator;
910 friend class AllocaSliceRewriter;
912 bool rewritePartition(
AllocaInst &AI, AllocaSlices &S,
914 int64_t BeginOffset, int64_t EndOffset,
916 bool splitAlloca(
AllocaInst &AI, AllocaSlices &S);
926 return new SROA(RequiresDomTree);
938 AllocaSlices::const_iterator E,
939 uint64_t EndOffset) {
941 bool IgnoreNonIntegralTypes =
false;
942 for (AllocaSlices::const_iterator I = B; I != E; ++
I) {
943 Use *U = I->getUse();
944 if (isa<IntrinsicInst>(*U->getUser()))
946 if (I->beginOffset() != B->beginOffset() || I->endOffset() != EndOffset)
950 if (
LoadInst *LI = dyn_cast<LoadInst>(U->getUser())) {
952 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(U->getUser())) {
953 UserTy = SI->getValueOperand()->
getType();
955 IgnoreNonIntegralTypes =
true;
959 if (
IntegerType *ITy = dyn_cast<IntegerType>(UserTy)) {
964 if (ITy->getBitWidth() % 8 != 0 ||
965 ITy->getBitWidth() / 8 > (EndOffset - B->beginOffset()))
975 }
else if (IgnoreNonIntegralTypes) {
979 if (Ty && Ty != UserTy)
980 IgnoreNonIntegralTypes =
true;
1012 unsigned MaxAlign = 0;
1013 bool HaveLoad =
false;
1029 if (BBI->mayWriteToMemory())
1071 DEBUG(
dbgs() <<
" original: " << PN <<
"\n");
1073 Type *LoadTy = cast<PointerType>(PN.
getType())->getElementType();
1074 IRBuilderTy PHIBuilder(&PN);
1076 PN.
getName() +
".sroa.speculated");
1096 IRBuilderTy PredBuilder(TI);
1099 InVal, (PN.
getName() +
".sroa.speculate.load." + Pred->
getName()));
1100 ++NumLoadsSpeculated;
1107 DEBUG(
dbgs() <<
" speculated to: " << *NewPN <<
"\n");
1151 DEBUG(
dbgs() <<
" original: " << SI <<
"\n");
1153 IRBuilderTy IRB(&SI);
1159 assert(LI->
isSimple() &&
"We only speculate simple loads");
1161 IRB.SetInsertPoint(LI);
1163 IRB.CreateLoad(TV, LI->
getName() +
".sroa.speculate.load.true");
1165 IRB.CreateLoad(FV, LI->
getName() +
".sroa.speculate.load.false");
1166 NumLoadsSpeculated += 2;
1177 LI->
getName() +
".sroa.speculated");
1179 DEBUG(
dbgs() <<
" speculated to: " << *V <<
"\n");
1192 if (Indices.
empty())
1197 if (Indices.
size() == 1 && cast<ConstantInt>(Indices.
back())->
isZero())
1200 return IRB.CreateInBoundsGEP(BasePtr, Indices,
"idx");
1216 return buildGEP(IRB, BasePtr, Indices);
1220 unsigned NumLayers = 0;
1221 Type *ElementTy = Ty;
1225 if (
SequentialType *SeqTy = dyn_cast<SequentialType>(ElementTy)) {
1226 ElementTy = SeqTy->getElementType();
1230 }
else if (
StructType *STy = dyn_cast<StructType>(ElementTy)) {
1231 if (STy->element_begin() == STy->element_end())
1233 ElementTy = *STy->element_begin();
1239 }
while (ElementTy != TargetTy);
1240 if (ElementTy != TargetTy)
1241 Indices.
erase(Indices.
end() - NumLayers, Indices.
end());
1243 return buildGEP(IRB, BasePtr, Indices);
1264 if (
VectorType *VecTy = dyn_cast<VectorType>(Ty)) {
1266 if (ElementSizeInBits % 8)
1269 APInt NumSkippedElements = Offset.
sdiv(ElementSize);
1270 if (NumSkippedElements.ugt(VecTy->getNumElements()))
1272 Offset -= NumSkippedElements * ElementSize;
1273 Indices.
push_back(IRB.getInt(NumSkippedElements));
1275 Offset, TargetTy, Indices);
1278 if (
ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) {
1279 Type *ElementTy = ArrTy->getElementType();
1281 APInt NumSkippedElements = Offset.
sdiv(ElementSize);
1282 if (NumSkippedElements.ugt(ArrTy->getNumElements()))
1285 Offset -= NumSkippedElements * ElementSize;
1286 Indices.
push_back(IRB.getInt(NumSkippedElements));
1334 if (ElementSize == 0)
1336 APInt NumSkippedElements = Offset.
sdiv(ElementSize);
1338 Offset -= NumSkippedElements * ElementSize;
1339 Indices.
push_back(IRB.getInt(NumSkippedElements));
1370 Value *OffsetPtr = 0;
1381 while (
GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) {
1383 if (!GEP->accumulateConstantOffset(DL, GEPOffset))
1385 Offset += GEPOffset;
1386 Ptr = GEP->getPointerOperand();
1387 if (!Visited.
insert(Ptr))
1397 if (OffsetPtr && OffsetPtr->
use_empty())
1398 if (
Instruction *I = dyn_cast<Instruction>(OffsetPtr))
1410 Int8PtrOffset = Offset;
1414 if (Operator::getOpcode(Ptr) == Instruction::BitCast) {
1415 Ptr = cast<Operator>(Ptr)->getOperand(0);
1416 }
else if (
GlobalAlias *GA = dyn_cast<GlobalAlias>(Ptr)) {
1417 if (GA->mayBeOverridden())
1419 Ptr = GA->getAliasee();
1424 }
while (Visited.
insert(Ptr));
1428 Int8Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy(),
1430 Int8PtrOffset = Offset;
1433 OffsetPtr = Int8PtrOffset == 0 ? Int8Ptr :
1434 IRB.CreateInBoundsGEP(Int8Ptr, IRB.getInt(Int8PtrOffset),
1441 Ptr = IRB.CreateBitCast(Ptr, PointerTy,
"cast");
1455 if (
IntegerType *OldITy = dyn_cast<IntegerType>(OldTy))
1456 if (
IntegerType *NewITy = dyn_cast<IntegerType>(NewTy))
1457 if (NewITy->getBitWidth() >= OldITy->getBitWidth())
1488 assert(
canConvertValue(DL, OldTy, NewTy) &&
"Value not convertable to type");
1493 if (
IntegerType *OldITy = dyn_cast<IntegerType>(OldTy))
1494 if (
IntegerType *NewITy = dyn_cast<IntegerType>(NewTy))
1495 if (NewITy->getBitWidth() > OldITy->getBitWidth())
1496 return IRB.CreateZExt(V, NewITy);
1504 return IRB.CreateIntToPtr(IRB.CreateBitCast(V, DL.
getIntPtrType(NewTy)),
1509 return IRB.CreateIntToPtr(IRB.CreateBitCast(V, DL.
getIntPtrType(NewTy)),
1512 return IRB.CreateIntToPtr(V, NewTy);
1521 return IRB.CreateBitCast(IRB.CreatePtrToInt(V, DL.
getIntPtrType(OldTy)),
1526 return IRB.CreateBitCast(IRB.CreatePtrToInt(V, DL.
getIntPtrType(OldTy)),
1529 return IRB.CreatePtrToInt(V, NewTy);
1532 return IRB.CreateBitCast(V, NewTy);
1540 const DataLayout &DL, AllocaSlices &S, uint64_t SliceBeginOffset,
1541 uint64_t SliceEndOffset,
VectorType *Ty, uint64_t ElementSize,
1542 AllocaSlices::const_iterator I) {
1544 uint64_t BeginOffset =
1545 std::max(I->beginOffset(), SliceBeginOffset) - SliceBeginOffset;
1546 uint64_t BeginIndex = BeginOffset / ElementSize;
1547 if (BeginIndex * ElementSize != BeginOffset ||
1550 uint64_t EndOffset =
1551 std::min(I->endOffset(), SliceEndOffset) - SliceBeginOffset;
1552 uint64_t EndIndex = EndOffset / ElementSize;
1553 if (EndIndex * ElementSize != EndOffset || EndIndex > Ty->
getNumElements())
1556 assert(EndIndex > BeginIndex &&
"Empty vector!");
1557 uint64_t NumElements = EndIndex - BeginIndex;
1563 Type::getIntNTy(Ty->
getContext(), NumElements * ElementSize * 8);
1565 Use *U = I->getUse();
1568 if (
MI->isVolatile())
1570 if (!I->isSplittable())
1572 }
else if (U->get()->getType()->getPointerElementType()->isStructTy()) {
1575 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(U->getUser())) {
1579 if (SliceBeginOffset > I->beginOffset() ||
1580 SliceEndOffset < I->endOffset()) {
1586 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(U->getUser())) {
1587 if (SI->isVolatile())
1590 if (SliceBeginOffset > I->beginOffset() ||
1591 SliceEndOffset < I->endOffset()) {
1615 uint64_t SliceBeginOffset, uint64_t SliceEndOffset,
1616 AllocaSlices::const_iterator I,
1617 AllocaSlices::const_iterator E,
1627 if (ElementSize % 8)
1630 "vector size not a multiple of element size?");
1635 SliceEndOffset, Ty, ElementSize, I))
1639 SUE = SplitUses.
end();
1642 SliceEndOffset, Ty, ElementSize, *SUI))
1654 uint64_t AllocBeginOffset,
1655 uint64_t Size, AllocaSlices &S,
1656 AllocaSlices::const_iterator I,
1657 bool &WholeAllocaOp) {
1658 uint64_t RelBegin = I->beginOffset() - AllocBeginOffset;
1659 uint64_t RelEnd = I->endOffset() - AllocBeginOffset;
1666 Use *U = I->getUse();
1668 if (
LoadInst *LI = dyn_cast<LoadInst>(U->getUser())) {
1671 if (RelBegin == 0 && RelEnd == Size)
1672 WholeAllocaOp =
true;
1676 }
else if (RelBegin != 0 || RelEnd != Size ||
1682 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(U->getUser())) {
1684 if (SI->isVolatile())
1686 if (RelBegin == 0 && RelEnd == Size)
1687 WholeAllocaOp =
true;
1688 if (
IntegerType *ITy = dyn_cast<IntegerType>(ValueTy)) {
1691 }
else if (RelBegin != 0 || RelEnd != Size ||
1697 }
else if (
MemIntrinsic *
MI = dyn_cast<MemIntrinsic>(U->getUser())) {
1698 if (
MI->isVolatile() || !isa<Constant>(
MI->getLength()))
1700 if (!I->isSplittable())
1702 }
else if (
IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
1721 uint64_t AllocBeginOffset, AllocaSlices &S,
1722 AllocaSlices::const_iterator I,
1723 AllocaSlices::const_iterator E,
1727 if (SizeInBits > IntegerType::MAX_INT_BITS)
1737 Type *IntTy = Type::getIntNTy(AllocaTy->
getContext(), SizeInBits);
1749 bool WholeAllocaOp = (I != E) ?
false : DL.
isLegalInteger(SizeInBits);
1753 S, I, WholeAllocaOp))
1757 SUE = SplitUses.
end();
1760 S, *SUI, WholeAllocaOp))
1763 return WholeAllocaOp;
1769 DEBUG(
dbgs() <<
" start: " << *V <<
"\n");
1772 "Element extends past full value");
1773 uint64_t ShAmt = 8*Offset;
1777 V = IRB.CreateLShr(V, ShAmt, Name +
".shift");
1778 DEBUG(
dbgs() <<
" shifted: " << *V <<
"\n");
1781 "Cannot extract to a larger integer!");
1783 V = IRB.CreateTrunc(V, Ty, Name +
".trunc");
1784 DEBUG(
dbgs() <<
" trunced: " << *V <<
"\n");
1793 assert(Ty->getBitWidth() <= IntTy->
getBitWidth() &&
1794 "Cannot insert a larger integer!");
1795 DEBUG(
dbgs() <<
" start: " << *V <<
"\n");
1797 V = IRB.CreateZExt(V, IntTy, Name +
".ext");
1798 DEBUG(
dbgs() <<
" extended: " << *V <<
"\n");
1801 "Element store outside of alloca store");
1802 uint64_t ShAmt = 8*Offset;
1806 V = IRB.CreateShl(V, ShAmt, Name +
".shift");
1807 DEBUG(
dbgs() <<
" shifted: " << *V <<
"\n");
1810 if (ShAmt || Ty->getBitWidth() < IntTy->
getBitWidth()) {
1812 Old = IRB.CreateAnd(Old, Mask, Name +
".mask");
1813 DEBUG(
dbgs() <<
" masked: " << *Old <<
"\n");
1814 V = IRB.CreateOr(Old, V, Name +
".insert");
1815 DEBUG(
dbgs() <<
" inserted: " << *V <<
"\n");
1821 unsigned BeginIndex,
unsigned EndIndex,
1824 unsigned NumElements = EndIndex - BeginIndex;
1825 assert(NumElements <= VecTy->getNumElements() &&
"Too many elements!");
1830 if (NumElements == 1) {
1831 V = IRB.CreateExtractElement(V, IRB.getInt32(BeginIndex),
1833 DEBUG(
dbgs() <<
" extract: " << *V <<
"\n");
1839 for (
unsigned i = BeginIndex; i != EndIndex; ++i)
1841 V = IRB.CreateShuffleVector(V, UndefValue::get(V->
getType()),
1842 ConstantVector::get(Mask),
1844 DEBUG(
dbgs() <<
" shuffle: " << *V <<
"\n");
1849 unsigned BeginIndex,
const Twine &
Name) {
1851 assert(VecTy &&
"Can only insert a vector into a vector");
1856 V = IRB.CreateInsertElement(Old, V, IRB.getInt32(BeginIndex),
1858 DEBUG(
dbgs() <<
" insert: " << *V <<
"\n");
1863 "Too many elements!");
1865 assert(V->
getType() == VecTy &&
"Vector type mismatch");
1877 if (i >= BeginIndex && i < EndIndex)
1878 Mask.
push_back(IRB.getInt32(i - BeginIndex));
1880 Mask.
push_back(UndefValue::get(IRB.getInt32Ty()));
1881 V = IRB.CreateShuffleVector(V, UndefValue::get(V->
getType()),
1882 ConstantVector::get(Mask),
1884 DEBUG(
dbgs() <<
" shuffle: " << *V <<
"\n");
1888 Mask.
push_back(IRB.getInt1(i >= BeginIndex && i < EndIndex));
1890 V = IRB.CreateSelect(ConstantVector::get(Mask), V, Old, Name +
"blend");
1892 DEBUG(
dbgs() <<
" blend: " << *V <<
"\n");
1903 class AllocaSliceRewriter :
public InstVisitor<AllocaSliceRewriter, bool> {
1912 const uint64_t NewAllocaBeginOffset, NewAllocaEndOffset;
1926 uint64_t ElementSize;
1935 uint64_t BeginOffset, EndOffset;
1943 bool IsUsedByRewrittenSpeculatableInstructions;
1950 AllocaSliceRewriter(
const DataLayout &DL, AllocaSlices &S, SROA &
Pass,
1952 uint64_t NewBeginOffset, uint64_t NewEndOffset,
1953 bool IsVectorPromotable =
false,
1954 bool IsIntegerPromotable =
false)
1955 : DL(DL), S(S), Pass(Pass), OldAI(OldAI), NewAI(NewAI),
1956 NewAllocaBeginOffset(NewBeginOffset), NewAllocaEndOffset(NewEndOffset),
1957 NewAllocaTy(NewAI.getAllocatedType()),
1959 ElementTy(VecTy ? VecTy->getElementType() : 0),
1960 ElementSize(VecTy ? DL.getTypeSizeInBits(ElementTy) / 8 : 0),
1961 IntTy(IsIntegerPromotable
1964 DL.getTypeSizeInBits(NewAI.getAllocatedType()))
1966 BeginOffset(), EndOffset(), IsSplittable(), IsSplit(), OldUse(),
1967 OldPtr(), IsUsedByRewrittenSpeculatableInstructions(
false),
1971 "Only multiple-of-8 sized vector elements are viable");
1974 assert((!IsVectorPromotable && !IsIntegerPromotable) ||
1975 IsVectorPromotable != IsIntegerPromotable);
1978 bool visit(AllocaSlices::const_iterator I) {
1979 bool CanSROA =
true;
1980 BeginOffset = I->beginOffset();
1981 EndOffset = I->endOffset();
1982 IsSplittable = I->isSplittable();
1984 BeginOffset < NewAllocaBeginOffset || EndOffset > NewAllocaEndOffset;
1986 OldUse = I->getUse();
1987 OldPtr = cast<Instruction>(OldUse->get());
1989 Instruction *OldUserI = cast<Instruction>(OldUse->getUser());
1990 IRB.SetInsertPoint(OldUserI);
1991 IRB.SetCurrentDebugLocation(OldUserI->getDebugLoc());
1994 CanSROA &=
visit(cast<Instruction>(OldUse->getUser()));
2010 bool isUsedByRewrittenSpeculatableInstructions()
const {
2011 return IsUsedByRewrittenSpeculatableInstructions;
2020 DEBUG(
dbgs() <<
" !!!! Cannot rewrite: " << I <<
"\n");
2024 Value *getAdjustedAllocaPtr(IRBuilderTy &IRB, uint64_t Offset,
2026 assert(Offset >= NewAllocaBeginOffset);
2028 Offset - NewAllocaBeginOffset),
2033 unsigned getOffsetAlign(uint64_t Offset) {
2037 return MinAlign(NewAIAlign, Offset);
2045 unsigned getOffsetTypeAlign(
Type *Ty, uint64_t Offset) {
2046 unsigned Align = getOffsetAlign(Offset);
2050 unsigned getIndex(uint64_t Offset) {
2051 assert(VecTy &&
"Can only call getIndex when rewriting a vector");
2052 uint64_t RelOffset = Offset - NewAllocaBeginOffset;
2053 assert(RelOffset / ElementSize < UINT32_MAX &&
"Index out of bounds");
2054 uint32_t Index = RelOffset / ElementSize;
2055 assert(Index * ElementSize == RelOffset);
2059 void deleteIfTriviallyDead(
Value *V) {
2062 Pass.DeadInsts.insert(I);
2065 Value *rewriteVectorizedLoadInst(uint64_t NewBeginOffset,
2066 uint64_t NewEndOffset) {
2067 unsigned BeginIndex = getIndex(NewBeginOffset);
2068 unsigned EndIndex = getIndex(NewEndOffset);
2069 assert(EndIndex > BeginIndex &&
"Empty vector!");
2076 Value *rewriteIntegerLoad(
LoadInst &LI, uint64_t NewBeginOffset,
2077 uint64_t NewEndOffset) {
2078 assert(IntTy &&
"We cannot insert an integer to the alloca");
2083 assert(NewBeginOffset >= NewAllocaBeginOffset &&
"Out of bounds offset");
2084 uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset;
2085 if (Offset > 0 || NewEndOffset < NewAllocaEndOffset)
2092 DEBUG(
dbgs() <<
" original: " << LI <<
"\n");
2094 assert(OldOp == OldPtr);
2097 assert(BeginOffset < NewAllocaEndOffset);
2098 assert(EndOffset > NewAllocaBeginOffset);
2099 uint64_t NewBeginOffset = std::max(BeginOffset, NewAllocaBeginOffset);
2100 uint64_t NewEndOffset = std::min(EndOffset, NewAllocaEndOffset);
2102 uint64_t Size = NewEndOffset - NewBeginOffset;
2106 bool IsPtrAdjusted =
false;
2109 V = rewriteVectorizedLoadInst(NewBeginOffset, NewEndOffset);
2111 V = rewriteIntegerLoad(LI, NewBeginOffset, NewEndOffset);
2112 }
else if (NewBeginOffset == NewAllocaBeginOffset &&
2114 V = IRB.CreateAlignedLoad(&NewAI, NewAI.
getAlignment(),
2118 V = IRB.CreateAlignedLoad(
2119 getAdjustedAllocaPtr(IRB, NewBeginOffset, LTy),
2120 getOffsetTypeAlign(TargetTy, NewBeginOffset - NewAllocaBeginOffset),
2122 IsPtrAdjusted =
true;
2129 "Only integer type loads and stores are split");
2131 "Split load isn't smaller than original load");
2134 "Non-byte-multiple bit width");
2152 Pass.DeadInsts.insert(&LI);
2153 deleteIfTriviallyDead(OldOp);
2159 uint64_t NewBeginOffset,
2160 uint64_t NewEndOffset) {
2162 unsigned BeginIndex = getIndex(NewBeginOffset);
2163 unsigned EndIndex = getIndex(NewEndOffset);
2164 assert(EndIndex > BeginIndex &&
"Empty vector!");
2165 unsigned NumElements = EndIndex - BeginIndex;
2166 assert(NumElements <= VecTy->getNumElements() &&
"Too many elements!");
2168 (NumElements == 1) ? ElementTy
2179 Pass.DeadInsts.insert(&SI);
2182 DEBUG(
dbgs() <<
" to: " << *Store <<
"\n");
2187 uint64_t NewBeginOffset, uint64_t NewEndOffset) {
2188 assert(IntTy &&
"We cannot extract an integer from the alloca");
2194 assert(BeginOffset >= NewAllocaBeginOffset &&
"Out of bounds offset");
2195 uint64_t Offset = BeginOffset - NewAllocaBeginOffset;
2201 Pass.DeadInsts.insert(&SI);
2203 DEBUG(
dbgs() <<
" to: " << *Store <<
"\n");
2208 DEBUG(
dbgs() <<
" original: " << SI <<
"\n");
2210 assert(OldOp == OldPtr);
2218 Pass.PostPromotionWorklist.insert(AI);
2221 assert(BeginOffset < NewAllocaEndOffset);
2222 assert(EndOffset > NewAllocaBeginOffset);
2223 uint64_t NewBeginOffset = std::max(BeginOffset, NewAllocaBeginOffset);
2224 uint64_t NewEndOffset = std::min(EndOffset, NewAllocaEndOffset);
2226 uint64_t Size = NewEndOffset - NewBeginOffset;
2230 "Only integer type loads and stores are split");
2233 "Non-byte-multiple bit width");
2240 return rewriteVectorizedStoreInst(V, SI, OldOp, NewBeginOffset,
2243 return rewriteIntegerStore(V, SI, NewBeginOffset, NewEndOffset);
2246 if (NewBeginOffset == NewAllocaBeginOffset &&
2247 NewEndOffset == NewAllocaEndOffset &&
2250 NewSI = IRB.CreateAlignedStore(V, &NewAI, NewAI.
getAlignment(),
2253 Value *NewPtr = getAdjustedAllocaPtr(IRB, NewBeginOffset,
2255 NewSI = IRB.CreateAlignedStore(
2256 V, NewPtr, getOffsetTypeAlign(
2257 V->
getType(), NewBeginOffset - NewAllocaBeginOffset),
2261 Pass.DeadInsts.insert(&SI);
2262 deleteIfTriviallyDead(OldOp);
2264 DEBUG(
dbgs() <<
" to: " << *NewSI <<
"\n");
2265 return NewSI->getPointerOperand() == &NewAI && !SI.
isVolatile();
2277 Value *getIntegerSplat(
Value *V,
unsigned Size) {
2278 assert(Size > 0 &&
"Expected a positive number of bytes.");
2280 assert(VTy->
getBitWidth() == 8 &&
"Expected an i8 value for the byte");
2285 V = IRB.CreateMul(IRB.CreateZExt(V, SplatIntTy,
"zext"),
2296 Value *getVectorSplat(
Value *V,
unsigned NumElements) {
2297 V = IRB.CreateVectorSplat(NumElements, V,
"vsplat");
2298 DEBUG(
dbgs() <<
" splat: " << *V <<
"\n");
2303 DEBUG(
dbgs() <<
" original: " << II <<
"\n");
2310 assert(BeginOffset >= NewAllocaBeginOffset);
2316 deleteIfTriviallyDead(OldPtr);
2321 Pass.DeadInsts.insert(&II);
2327 assert(BeginOffset < NewAllocaEndOffset);
2328 assert(EndOffset > NewAllocaBeginOffset);
2329 uint64_t NewBeginOffset = std::max(BeginOffset, NewAllocaBeginOffset);
2330 uint64_t NewEndOffset = std::min(EndOffset, NewAllocaEndOffset);
2331 uint64_t SliceOffset = NewBeginOffset - NewAllocaBeginOffset;
2335 if (!VecTy && !IntTy &&
2336 (BeginOffset > NewAllocaBeginOffset ||
2337 EndOffset < NewAllocaEndOffset ||
2347 DEBUG(
dbgs() <<
" to: " << *New <<
"\n");
2360 assert(ElementTy == ScalarTy);
2362 unsigned BeginIndex = getIndex(NewBeginOffset);
2363 unsigned EndIndex = getIndex(NewEndOffset);
2364 assert(EndIndex > BeginIndex &&
"Empty vector!");
2365 unsigned NumElements = EndIndex - BeginIndex;
2366 assert(NumElements <= VecTy->getNumElements() &&
"Too many elements!");
2371 if (NumElements > 1)
2372 Splat = getVectorSplat(Splat, NumElements);
2382 uint64_t Size = NewEndOffset - NewBeginOffset;
2383 V = getIntegerSplat(II.
getValue(), Size);
2385 if (IntTy && (BeginOffset != NewAllocaBeginOffset ||
2386 EndOffset != NewAllocaBeginOffset)) {
2390 uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset;
2393 assert(V->
getType() == IntTy &&
2394 "Wrong type for an alloca wide integer!");
2399 assert(NewBeginOffset == NewAllocaBeginOffset);
2400 assert(NewEndOffset == NewAllocaEndOffset);
2403 if (
VectorType *AllocaVecTy = dyn_cast<VectorType>(AllocaTy))
2404 V = getVectorSplat(V, AllocaVecTy->getNumElements());
2412 DEBUG(
dbgs() <<
" to: " << *New <<
"\n");
2420 DEBUG(
dbgs() <<
" original: " << II <<
"\n");
2423 assert(BeginOffset < NewAllocaEndOffset);
2424 assert(EndOffset > NewAllocaBeginOffset);
2425 uint64_t NewBeginOffset = std::max(BeginOffset, NewAllocaBeginOffset);
2426 uint64_t NewEndOffset = std::min(EndOffset, NewAllocaEndOffset);
2433 APInt RelOffset(IntPtrWidth, NewBeginOffset - BeginOffset);
2436 uint64_t SliceOffset = NewBeginOffset - NewAllocaBeginOffset;
2439 MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
2449 if (!IsSplittable) {
2455 II.
setSource(getAdjustedAllocaPtr(IRB, BeginOffset,
2462 deleteIfTriviallyDead(OldOp);
2474 = !VecTy && !IntTy && (BeginOffset > NewAllocaBeginOffset ||
2475 EndOffset < NewAllocaEndOffset ||
2481 if (EmitMemCpy && &OldAI == &NewAI) {
2483 assert(NewBeginOffset == BeginOffset);
2486 if (NewEndOffset != EndOffset)
2488 NewEndOffset - NewBeginOffset));
2492 Pass.DeadInsts.insert(&II);
2499 Pass.Worklist.insert(AI);
2507 OtherPtr =
getAdjustedPtr(IRB, DL, OtherPtr, RelOffset, OtherPtrTy);
2509 Value *OurPtr = getAdjustedAllocaPtr(
2510 IRB, NewBeginOffset,
2515 CallInst *New = IRB.CreateMemCpy(IsDest ? OurPtr : OtherPtr,
2516 IsDest ? OtherPtr : OurPtr,
2519 DEBUG(
dbgs() <<
" to: " << *New <<
"\n");
2529 bool IsWholeAlloca = NewBeginOffset == NewAllocaBeginOffset &&
2530 NewEndOffset == NewAllocaEndOffset;
2531 uint64_t Size = NewEndOffset - NewBeginOffset;
2532 unsigned BeginIndex = VecTy ? getIndex(NewBeginOffset) : 0;
2533 unsigned EndIndex = VecTy ? getIndex(NewEndOffset) : 0;
2534 unsigned NumElements = EndIndex - BeginIndex;
2539 if (VecTy && !IsWholeAlloca) {
2540 if (NumElements == 1)
2546 }
else if (IntTy && !IsWholeAlloca) {
2551 Value *DstPtr = &NewAI;
2556 if (VecTy && !IsWholeAlloca && !IsDest) {
2557 Src = IRB.CreateAlignedLoad(&NewAI, NewAI.
getAlignment(),
2560 }
else if (IntTy && !IsWholeAlloca && !IsDest) {
2561 Src = IRB.CreateAlignedLoad(&NewAI, NewAI.
getAlignment(),
2564 uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset;
2567 Src = IRB.CreateAlignedLoad(SrcPtr, Align, II.
isVolatile(),
2571 if (VecTy && !IsWholeAlloca && IsDest) {
2575 }
else if (IntTy && !IsWholeAlloca && IsDest) {
2579 uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset;
2585 IRB.CreateAlignedStore(Src, DstPtr, Align, II.
isVolatile()));
2587 DEBUG(
dbgs() <<
" to: " << *Store <<
"\n");
2594 DEBUG(
dbgs() <<
" original: " << II <<
"\n");
2598 assert(BeginOffset < NewAllocaEndOffset);
2599 assert(EndOffset > NewAllocaBeginOffset);
2600 uint64_t NewBeginOffset = std::max(BeginOffset, NewAllocaBeginOffset);
2601 uint64_t NewEndOffset = std::min(EndOffset, NewAllocaEndOffset);
2604 Pass.DeadInsts.insert(&II);
2608 NewEndOffset - NewBeginOffset);
2613 New = IRB.CreateLifetimeStart(Ptr, Size);
2615 New = IRB.CreateLifetimeEnd(Ptr, Size);
2618 DEBUG(
dbgs() <<
" to: " << *New <<
"\n");
2623 DEBUG(
dbgs() <<
" original: " << PN <<
"\n");
2624 assert(BeginOffset >= NewAllocaBeginOffset &&
"PHIs are unsplittable");
2625 assert(EndOffset <= NewAllocaEndOffset &&
"PHIs are unsplittable");
2631 IRBuilderTy PtrBuilder(OldPtr);
2636 getAdjustedAllocaPtr(PtrBuilder, BeginOffset, OldPtr->getType());
2638 std::replace(PN.
op_begin(), PN.
op_end(), cast<Value>(OldPtr), NewPtr);
2641 deleteIfTriviallyDead(OldPtr);
2647 Pass.SpeculatablePHIs.insert(&PN);
2648 IsUsedByRewrittenSpeculatableInstructions =
true;
2656 DEBUG(
dbgs() <<
" original: " << SI <<
"\n");
2658 "Pointer isn't an operand!");
2659 assert(BeginOffset >= NewAllocaBeginOffset &&
"Selects are unsplittable");
2660 assert(EndOffset <= NewAllocaEndOffset &&
"Selects are unsplittable");
2662 Value *NewPtr = getAdjustedAllocaPtr(IRB, BeginOffset, OldPtr->getType());
2670 deleteIfTriviallyDead(OldPtr);
2676 Pass.SpeculatableSelects.insert(&SI);
2677 IsUsedByRewrittenSpeculatableInstructions =
true;
2693 class AggLoadStoreRewriter :
public InstVisitor<AggLoadStoreRewriter, bool> {
2710 AggLoadStoreRewriter(
const DataLayout &DL) : DL(DL) {}
2715 DEBUG(
dbgs() <<
" Rewriting FCA loads and stores...\n");
2717 bool Changed =
false;
2718 while (!Queue.empty()) {
2719 U = Queue.pop_back_val();
2720 Changed |=
visit(cast<Instruction>(U->getUser()));
2732 Queue.push_back(&UI.getUse());
2739 template <
typename Derived>
2757 : IRB(InsertionPoint), GEPIndices(1, IRB.getInt32(0)), Ptr(Ptr) {}
2775 return static_cast<Derived *>(
this)->emitFunc(Ty, Agg, Name);
2777 if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
2778 unsigned OldSize = Indices.size();
2780 for (
unsigned Idx = 0, Size = ATy->getNumElements(); Idx != Size;
2782 assert(Indices.size() == OldSize &&
"Did not return to the old size");
2783 Indices.push_back(Idx);
2784 GEPIndices.push_back(IRB.getInt32(Idx));
2785 emitSplitOps(ATy->getElementType(), Agg, Name +
"." +
Twine(Idx));
2786 GEPIndices.pop_back();
2792 if (
StructType *STy = dyn_cast<StructType>(Ty)) {
2793 unsigned OldSize = Indices.size();
2795 for (
unsigned Idx = 0, Size = STy->getNumElements(); Idx != Size;
2797 assert(Indices.size() == OldSize &&
"Did not return to the old size");
2798 Indices.push_back(Idx);
2799 GEPIndices.push_back(IRB.getInt32(Idx));
2800 emitSplitOps(STy->getElementType(Idx), Agg, Name +
"." +
Twine(Idx));
2801 GEPIndices.pop_back();
2811 struct LoadOpSplitter :
public OpSplitter<LoadOpSplitter> {
2813 : OpSplitter<LoadOpSplitter>(InsertionPoint, Ptr) {}
2820 Value *GEP = IRB.CreateInBoundsGEP(Ptr, GEPIndices, Name +
".gep");
2821 Value *
Load = IRB.CreateLoad(GEP, Name +
".load");
2822 Agg = IRB.CreateInsertValue(Agg, Load, Indices, Name +
".insert");
2823 DEBUG(
dbgs() <<
" to: " << *Load <<
"\n");
2833 DEBUG(
dbgs() <<
" original: " << LI <<
"\n");
2834 LoadOpSplitter Splitter(&LI, *U);
2842 struct StoreOpSplitter :
public OpSplitter<StoreOpSplitter> {
2844 : OpSplitter<StoreOpSplitter>(InsertionPoint, Ptr) {}
2851 Value *Store = IRB.CreateStore(
2852 IRB.CreateExtractValue(Agg, Indices, Name +
".extract"),
2853 IRB.CreateInBoundsGEP(Ptr, GEPIndices, Name +
".gep"));
2855 DEBUG(
dbgs() <<
" to: " << *Store <<
"\n");
2867 DEBUG(
dbgs() <<
" original: " << SI <<
"\n");
2868 StoreOpSplitter Splitter(&SI, *U);
2884 bool visitPHINode(
PHINode &PN) {
2909 if (
ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) {
2910 InnerTy = ArrTy->getElementType();
2911 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
2914 InnerTy = STy->getElementType(Index);
2940 uint64_t Offset, uint64_t Size) {
2949 if (SeqTy->isPointerTy())
2952 Type *ElementTy = SeqTy->getElementType();
2954 uint64_t NumSkippedElements = Offset / ElementSize;
2955 if (
ArrayType *ArrTy = dyn_cast<ArrayType>(SeqTy)) {
2956 if (NumSkippedElements >= ArrTy->getNumElements())
2958 }
else if (
VectorType *VecTy = dyn_cast<VectorType>(SeqTy)) {
2959 if (NumSkippedElements >= VecTy->getNumElements())
2962 Offset -= NumSkippedElements * ElementSize;
2965 if (Offset > 0 || Size < ElementSize) {
2967 if ((Offset + Size) > ElementSize)
2972 assert(Offset == 0);
2974 if (Size == ElementSize)
2976 assert(Size > ElementSize);
2977 uint64_t NumElements = Size / ElementSize;
2978 if (NumElements * ElementSize != Size)
2980 return ArrayType::get(ElementTy, NumElements);
2990 uint64_t EndOffset = Offset + Size;
2999 if (Offset >= ElementSize)
3003 if (Offset > 0 || Size < ElementSize) {
3004 if ((Offset + Size) > ElementSize)
3008 assert(Offset == 0);
3010 if (Size == ElementSize)
3015 if (EndOffset < SL->getSizeInBytes()) {
3017 if (Index == EndIndex)
3027 assert(Index < EndIndex);
3035 if (Size != SubSL->getSizeInBytes())
3051 bool SROA::rewritePartition(
AllocaInst &AI, AllocaSlices &S,
3053 int64_t BeginOffset, int64_t EndOffset,
3055 assert(BeginOffset < EndOffset);
3056 uint64_t SliceSize = EndOffset - BeginOffset;
3064 SliceTy = CommonUseTy;
3067 BeginOffset, SliceSize))
3068 SliceTy = TypePartitionTy;
3069 if ((!SliceTy || (SliceTy->
isArrayTy() &&
3072 SliceTy = Type::getIntNTy(*
C, SliceSize * 8);
3074 SliceTy = ArrayType::get(Type::getInt8Ty(*
C), SliceSize);
3078 *DL, SliceTy, S, BeginOffset, EndOffset, B, E, SplitUses);
3080 bool IsIntegerPromotable =
3081 !IsVectorPromotable &&
3090 assert(BeginOffset == 0 &&
3091 "Non-zero begin offset but same alloca type");
3103 Alignment =
MinAlign(Alignment, BeginOffset);
3106 if (Alignment <= DL->getABITypeAlignment(SliceTy))
3108 NewAI =
new AllocaInst(SliceTy, 0, Alignment,
3113 DEBUG(
dbgs() <<
"Rewriting alloca partition "
3114 <<
"[" << BeginOffset <<
"," << EndOffset <<
") to: " << *NewAI
3120 unsigned PPWOldSize = PostPromotionWorklist.size();
3121 unsigned SPOldSize = SpeculatablePHIs.size();
3122 unsigned SSOldSize = SpeculatableSelects.size();
3123 unsigned NumUses = 0;
3125 AllocaSliceRewriter
Rewriter(*DL, S, *
this, AI, *NewAI, BeginOffset,
3126 EndOffset, IsVectorPromotable,
3127 IsIntegerPromotable);
3128 bool Promotable =
true;
3130 SUE = SplitUses.
end();
3131 SUI != SUE; ++SUI) {
3134 Promotable &=
Rewriter.visit(*SUI);
3144 NumAllocaPartitionUses += NumUses;
3145 MaxUsesPerAllocaPartition =
3146 std::max<unsigned>(NumUses, MaxUsesPerAllocaPartition);
3148 if (Promotable && !
Rewriter.isUsedByRewrittenSpeculatableInstructions()) {
3149 DEBUG(
dbgs() <<
" and queuing for promotion\n");
3150 PromotableAllocas.push_back(NewAI);
3151 }
else if (NewAI != &AI ||
3153 Rewriter.isUsedByRewrittenSpeculatableInstructions())) {
3164 Worklist.insert(NewAI);
3169 while (PostPromotionWorklist.size() > PPWOldSize)
3170 PostPromotionWorklist.pop_back();
3171 while (SpeculatablePHIs.size() > SPOldSize)
3172 SpeculatablePHIs.pop_back();
3173 while (SpeculatableSelects.size() > SSOldSize)
3174 SpeculatableSelects.pop_back();
3181 struct IsSliceEndLessOrEqualTo {
3182 uint64_t UpperBound;
3184 IsSliceEndLessOrEqualTo(uint64_t UpperBound) : UpperBound(UpperBound) {}
3187 return I->endOffset() <= UpperBound;
3194 uint64_t &MaxSplitUseEndOffset, uint64_t Offset) {
3195 if (Offset >= MaxSplitUseEndOffset) {
3197 MaxSplitUseEndOffset = 0;
3201 size_t SplitUsesOldSize = SplitUses.
size();
3202 SplitUses.
erase(std::remove_if(SplitUses.
begin(), SplitUses.
end(),
3203 IsSliceEndLessOrEqualTo(Offset)),
3205 if (SplitUsesOldSize == SplitUses.
size())
3209 MaxSplitUseEndOffset = 0;
3211 SUI = SplitUses.
begin(),
3212 SUE = SplitUses.
end();
3214 MaxSplitUseEndOffset = std::max((*SUI)->endOffset(), MaxSplitUseEndOffset);
3219 bool SROA::splitAlloca(
AllocaInst &AI, AllocaSlices &S) {
3220 if (S.begin() == S.end())
3223 unsigned NumPartitions = 0;
3224 bool Changed =
false;
3226 uint64_t MaxSplitUseEndOffset = 0;
3228 uint64_t BeginOffset = S.begin()->beginOffset();
3231 SI != SE; SI = SJ) {
3232 uint64_t MaxEndOffset = SI->endOffset();
3234 if (!SI->isSplittable()) {
3237 assert(BeginOffset == SI->beginOffset());
3241 while (SJ != SE && SJ->beginOffset() < MaxEndOffset) {
3242 if (!SJ->isSplittable())
3243 MaxEndOffset = std::max(MaxEndOffset, SJ->endOffset());
3247 assert(SI->isSplittable());
3250 while (SJ != SE && SJ->beginOffset() < MaxEndOffset &&
3251 SJ->isSplittable()) {
3252 MaxEndOffset = std::max(MaxEndOffset, SJ->endOffset());
3258 if (SJ != SE && SJ->beginOffset() < MaxEndOffset) {
3259 assert(!SJ->isSplittable());
3260 MaxEndOffset = SJ->beginOffset();
3266 if (BeginOffset < MaxEndOffset) {
3269 rewritePartition(AI, S, SI, SJ, BeginOffset, MaxEndOffset, SplitUses);
3278 if (SK->isSplittable() && SK->endOffset() > MaxEndOffset) {
3280 MaxSplitUseEndOffset = std::max(SK->endOffset(), MaxSplitUseEndOffset);
3284 if (SJ == SE && SplitUses.
empty())
3289 if (SplitUses.
empty() || (SJ != SE && MaxEndOffset == SJ->beginOffset())) {
3290 BeginOffset = SJ->beginOffset();
3297 if (SJ != SE && SJ->isSplittable() &&
3298 MaxSplitUseEndOffset > SJ->beginOffset()) {
3299 BeginOffset = MaxEndOffset;
3305 uint64_t PostSplitEndOffset =
3306 SJ == SE ? MaxSplitUseEndOffset : SJ->beginOffset();
3308 Changed |= rewritePartition(AI, S, SJ, SJ, MaxEndOffset, PostSplitEndOffset,
3316 PostSplitEndOffset);
3319 BeginOffset = SJ->beginOffset();
3322 NumAllocaPartitions += NumPartitions;
3323 MaxPartitionsPerAlloca =
3324 std::max<unsigned>(NumPartitions, MaxPartitionsPerAlloca);
3335 DEBUG(
dbgs() <<
"SROA alloca: " << AI <<
"\n");
3336 ++NumAllocasAnalyzed;
3349 bool Changed =
false;
3353 AggLoadStoreRewriter AggRewriter(*DL);
3354 Changed |= AggRewriter.rewrite(AI);
3357 AllocaSlices S(*DL, AI);
3363 for (AllocaSlices::dead_user_iterator DI = S.dead_user_begin(),
3364 DE = S.dead_user_end();
3367 (*DI)->replaceAllUsesWith(UndefValue::get((*DI)->getType()));
3368 DeadInsts.insert(*DI);
3370 for (AllocaSlices::dead_op_iterator DO = S.dead_op_begin(),
3371 DE = S.dead_op_end();
3375 **DO = UndefValue::get(OldV->
getType());
3376 if (
Instruction *OldI = dyn_cast<Instruction>(OldV))
3379 DeadInsts.insert(OldI);
3384 if (S.begin() == S.end())
3387 Changed |= splitAlloca(AI, S);
3390 while (!SpeculatablePHIs.empty())
3393 DEBUG(
dbgs() <<
" Speculating Selects\n");
3394 while (!SpeculatableSelects.empty())
3410 while (!DeadInsts.empty()) {
3412 DEBUG(
dbgs() <<
"Deleting dead instruction: " << *I <<
"\n");
3417 if (
Instruction *U = dyn_cast<Instruction>(*OI)) {
3421 DeadInsts.insert(U);
3424 if (
AllocaInst *AI = dyn_cast<AllocaInst>(I))
3425 DeletedAllocas.
insert(AI);
3437 if (Visited.
insert(cast<Instruction>(*UI)))
3438 Worklist.
push_back(cast<Instruction>(*UI));
3449 bool SROA::promoteAllocas(
Function &
F) {
3450 if (PromotableAllocas.empty())
3453 NumPromoted += PromotableAllocas.size();
3456 DEBUG(
dbgs() <<
"Promoting allocas with mem2reg...\n");
3458 PromotableAllocas.clear();
3462 DEBUG(
dbgs() <<
"Promoting allocas with SSAUpdater...\n");
3472 for (
unsigned Idx = 0, Size = PromotableAllocas.size(); Idx != Size; ++Idx) {
3480 while (!Worklist.
empty()) {
3497 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
3499 Insts.push_back(LI);
3502 if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
3504 Insts.push_back(SI);
3514 AllocaPromoter(Insts, SSA, *AI, DIB).run(Insts);
3515 while (!DeadInsts.
empty())
3520 PromotableAllocas.clear();
3526 class IsAllocaInSet {
3533 IsAllocaInSet(
const SetType &Set) : Set(Set) {}
3534 bool operator()(
AllocaInst *AI)
const {
return Set.count(AI); }
3538 bool SROA::runOnFunction(
Function &F) {
3541 DL = getAnalysisIfAvailable<DataLayout>();
3543 DEBUG(
dbgs() <<
" Skipping SROA -- no target data!\n");
3546 DT = getAnalysisIfAvailable<DominatorTree>();
3551 if (
AllocaInst *AI = dyn_cast<AllocaInst>(I))
3554 bool Changed =
false;
3560 while (!Worklist.
empty()) {
3562 deleteDeadInstructions(DeletedAllocas);
3566 if (!DeletedAllocas.
empty()) {
3567 Worklist.remove_if(IsAllocaInSet(DeletedAllocas));
3568 PostPromotionWorklist.remove_if(IsAllocaInSet(DeletedAllocas));
3569 PromotableAllocas.
erase(std::remove_if(PromotableAllocas.begin(),
3570 PromotableAllocas.end(),
3571 IsAllocaInSet(DeletedAllocas)),
3572 PromotableAllocas.end());
3573 DeletedAllocas.
clear();
3577 Changed |= promoteAllocas(F);
3579 Worklist = PostPromotionWorklist;
3580 PostPromotionWorklist.
clear();
3581 }
while (!Worklist.
empty());
3587 if (RequiresDomTree)
unsigned getAlignment() const
Scalar Replacement Of static false Type * findCommonType(AllocaSlices::const_iterator B, AllocaSlices::const_iterator E, uint64_t EndOffset)
RetTy visitSelectInst(SelectInst &I)
Value * getValueOperand()
void push_back(const T &Elt)
static void removeFinishedSplitUses(SmallVectorImpl< AllocaSlices::iterator > &SplitUses, uint64_t &MaxSplitUseEndOffset, uint64_t Offset)
const_iterator end(StringRef path)
Get end iterator over path.
IntegerType * getType() const
Value * getPointerOperand()
RetTy visitMemSetInst(MemSetInst &I)
Helper class for SSA formation on a set of values defined in multiple blocks.
void addIncoming(Value *V, BasicBlock *BB)
LLVMContext & getContext() const
LLVM Argument representation.
Base class for instruction visitors.
uint64_t getZExtValue() const
Get zero extended value.
Intrinsic::ID getIntrinsicID() const
ConstantInt * getAlignmentCst() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
This class represents zero extension of integer types.
static Value * extractInteger(const DataLayout &DL, IRBuilderTy &IRB, Value *V, IntegerType *Ty, uint64_t Offset, const Twine &Name)
bool mayHaveSideEffects() 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...
static cl::opt< bool > ForceSSAUpdater("force-ssa-updater", cl::init(false), cl::Hidden)
iterator insert(iterator I, const T &Elt)
const_iterator begin(StringRef path)
Get begin iterator over path.
Scalar Replacement Of Aggregates
MDNode - a tuple of other values.
void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AliasSetTracker *AST=0)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align, const DataLayout *TD=0)
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
This class represents a sign extension of integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
RetTy visitPHINode(PHINode &I)
void setAlignment(Constant *A)
void setDebugLoc(const DebugLoc &Loc)
setDebugLoc - Set the debug location information for this instruction.
static void enqueueUsersInWorklist(Instruction &I, SmallVectorImpl< Instruction * > &Worklist, SmallPtrSet< Instruction *, 8 > &Visited)
LoopInfoBase< BlockT, LoopT > * LI
static bool isSafePHIToSpeculate(PHINode &PN, const DataLayout *DL=0)
Builder for the alloca slices.
Type * getPointerElementType() const
StringRef getName() const
bool isSingleValueType() const
element_iterator element_end() const
bool isNegative() const
Determine sign of this APInt.
bool isArrayAllocation() const
AnalysisUsage & addRequired()
STATISTIC(NumAllocasAnalyzed,"Number of allocas analyzed for replacement")
#define INITIALIZE_PASS_DEPENDENCY(depName)
std::string str() const
str - Return the twine contents as a std::string.
static Value * getPointerOperand(Instruction &Inst)
Type::subtype_iterator element_iterator
const StructLayout * getStructLayout(StructType *Ty) const
RetTy visitIntrinsicInst(IntrinsicInst &I)
const APInt & getValue() const
Return the constant's value.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Type * getArrayElementType() const
static Type * getTypePartition(const DataLayout &DL, Type *Ty, uint64_t Offset, uint64_t Size)
Try to find a partition of the aggregate type passed in for a given offset and size.
static Value * getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, APInt Offset, Type *PointerTy)
Compute an adjusted pointer from Ptr by Offset bytes where the resulting pointer has PointerTy...
FunctionPass * createSROAPass(bool RequiresDomTree=true)
#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...
static Value * convertValue(const DataLayout &DL, IRBuilderTy &IRB, Value *V, Type *NewTy)
Generic routine to convert an SSA value to a value of a different type.
static Value * getNaturalGEPRecursively(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, Type *Ty, APInt &Offset, Type *TargetTy, SmallVectorImpl< Value * > &Indices)
Recursively compute indices for a natural GEP.
element_iterator element_begin() const
Type * getAllocatedType() const
ID
LLVM Calling Convention Representation.
void visit(Iterator Start, Iterator End)
A base class for visitors over the uses of a pointer value.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static bool isSafeSelectToSpeculate(SelectInst &SI, const DataLayout *DL=0)
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
Get the constant's value with a saturation limit.
This class represents a no-op cast from one type to another.
ConstantFolder - Create constants with minimum, target independent, folding.
void replaceAllUsesWith(Value *V)
static Constant * getUDiv(Constant *C1, Constant *C2, bool isExact=false)
unsigned getNumElements() const
Return the number of elements in the Vector type.
RetTy visitMemTransferInst(MemTransferInst &I)
static Value * buildGEP(IRBuilderTy &IRB, Value *BasePtr, SmallVectorImpl< Value * > &Indices)
Build a GEP out of a base pointer and indices.
Type * getElementType() const
static bool canConvertValue(const DataLayout &DL, Type *OldTy, Type *NewTy)
Test whether we can convert a value from the old to the new type.
unsigned getNumIncomingValues() const
uint64_t getElementOffset(unsigned Idx) const
unsigned getNumSuccessors() const
Scalar Replacement Of false
initializer< Ty > init(const Ty &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
LLVM Basic Block Representation.
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Type * getElementType(unsigned N) const
LLVM Constant Representation.
PointerType * getType() const
const Value * getCondition() const
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
unsigned getAlignment() const
Value * getRawDest() const
Value * stripInBoundsOffsets()
Strips off unneeded pointer casts and any in-bounds offsets from the specified value, returning the original pointer value.
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)
#define LLVM_ATTRIBUTE_UNUSED
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
static Value * getNaturalGEPWithType(IRBuilderTy &IRB, const DataLayout &DL, Value *BasePtr, Type *Ty, Type *TargetTy, SmallVectorImpl< Value * > &Indices)
Get a natural GEP off of the BasePtr walking through Ty toward TargetTy without changing the offset o...
APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const
Signed division function for APInt.
Value * getOperand(unsigned i) const
Value * getPointerOperand()
static bool isVectorPromotionViable(const DataLayout &DL, Type *AllocaTy, AllocaSlices &S, uint64_t SliceBeginOffset, uint64_t SliceEndOffset, AllocaSlices::const_iterator I, AllocaSlices::const_iterator E, ArrayRef< AllocaSlices::iterator > SplitUses)
Test whether the given alloca partitioning and range of slices can be promoted to a vector...
Integer representation type.
RetTy visitLoadInst(LoadInst &I)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void setAlignment(unsigned Align)
static bool isVectorPromotionViableForSlice(const DataLayout &DL, AllocaSlices &S, uint64_t SliceBeginOffset, uint64_t SliceEndOffset, VectorType *Ty, uint64_t ElementSize, AllocaSlices::const_iterator I)
Test whether the given slice use can be promoted to a vector.
static Constant * getAllOnesValue(Type *Ty)
Get the all ones value.
static UndefValue * get(Type *T)
iterator erase(iterator I)
LLVMContext & getContext() const
All values hold a context through their type.
static bool isIntegerWideningViableForSlice(const DataLayout &DL, Type *AllocaTy, uint64_t AllocBeginOffset, uint64_t Size, AllocaSlices &S, AllocaSlices::const_iterator I, bool &WholeAllocaOp)
Test whether a slice of an alloca is valid for integer widening.
MDNode * getVariable() const
PointerType * getPointerTo(unsigned AddrSpace=0)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
const Value * getTrueValue() const
void setMetadata(unsigned KindID, MDNode *Node)
static Type * stripAggregateTypeWrapping(const DataLayout &DL, Type *Ty)
Strip aggregate type wrapping.
This provides the default implementation of the IRBuilder 'InsertHelper' method that is called whenev...
static bool isZero(Value *V, DataLayout *DL)
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
unsigned getABITypeAlignment(Type *Ty) const
unsigned getIntegerBitWidth() const
Class for constant integers.
Value * getIncomingValue(unsigned i) const
uint64_t getTypeAllocSize(Type *Ty) const
friend const_iterator begin(StringRef path)
Get begin iterator over path.
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder)
MDNode * getMetadata(unsigned KindID) const
static Value * insertVector(IRBuilderTy &IRB, Value *Old, Value *V, unsigned BeginIndex, const Twine &Name)
#define LLVM_ATTRIBUTE_NOINLINE
Value * getLength() const
uint64_t getSizeInBytes() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getElementContainingOffset(uint64_t Offset) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
const BasicBlock & getEntryBlock() const
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Value * getArgOperand(unsigned i) const
Class for arbitrary precision integers.
void initializeSROAPass(PassRegistry &)
RetTy visitStoreInst(StoreInst &I)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB, BasicBlock::iterator InsertPt) const
static Value * insertInteger(const DataLayout &DL, IRBuilderTy &IRB, Value *Old, Value *V, uint64_t Offset, const Twine &Name)
Virtual Register Rewriter
bool isDereferenceablePointer() const
bool operator!=(uint64_t V1, const APInt &V2)
uint64_t MinAlign(uint64_t A, uint64_t B)
static Constant * getZExt(Constant *C, Type *Ty)
bool isLegalInteger(unsigned Width) const
INITIALIZE_PASS_BEGIN(SROA,"sroa","Scalar Replacement Of Aggregates", false, false) INITIALIZE_PASS_END(SROA
unsigned getAlignment() const
static void speculateSelectInstLoads(SelectInst &SI)
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
unsigned getPointerSizeInBits(unsigned AS=0) const
void setSource(Value *Ptr)
const Type * getScalarType() const
static bool isIntegerWideningViable(const DataLayout &DL, Type *AllocaTy, uint64_t AllocBeginOffset, AllocaSlices &S, AllocaSlices::const_iterator I, AllocaSlices::const_iterator E, ArrayRef< AllocaSlices::iterator > SplitUses)
Test whether the given alloca partition's integer operations can be widened to promotable ones...
static Value * extractVector(IRBuilderTy &IRB, Value *V, unsigned BeginIndex, unsigned EndIndex, const Twine &Name)
uint64_t getTypeStoreSize(Type *Ty) const
Value * getRawSource() const
LLVM Value Representation.
A vector that has set insertion semantics.
static VectorType * get(Type *ElementType, unsigned NumElements)
APInt shl(const APInt &LHS, unsigned shiftAmt)
Left-shift function.
bool isTriviallyEmpty() const
static void speculatePHINodeLoads(PHINode &PN)
uint64_t getTypeSizeInBits(Type *Ty) const
ItTy prior(ItTy it, Dist n)
SliceBuilder(const DataLayout &DL, AllocaInst &AI, AllocaSlices &S)
const Value * getFalseValue() const
APInt LLVM_ATTRIBUTE_UNUSED_RESULT zext(unsigned width) const
Zero extend to a new width.
bool operator==(uint64_t V1, const APInt &V2)
void visitInstruction(Instruction &I)
tier< T1, T2 > tie(T1 &f, T2 &s)
Value * getPointerOperand()
const BasicBlock * getParent() const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
static Value * getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr, APInt Offset, Type *TargetTy, SmallVectorImpl< Value * > &Indices)
Get a natural GEP from a base pointer to a particular offset and resulting in a particular type...
static Value * foldSelectInst(SelectInst &SI)
#define LLVM_ATTRIBUTE_USED